I am trying to find a good way to pass parameters from my native unity plugin in objc/swift to C# unity.

It seems that I will need to use Marshall but I couldn't find a good example of this anywhere.

The only thing I did found is the UnitySendMessage, but that passes strings only as parameters, and even those are limited to 1024 bytes, which is not enough for a JSON representation of the objects, and handling multiple messages seems a bit of an overkill for this.

The idea is to be able to question the plugin for object detection from a MTLTexture and return the objects that are recognised.

Code samples:


import Foundation
import UIKit
import Vision

@objc public class SwiftBridge: NSObject {

  var delegate: DelegateCallbackFunction?

  @objc static let shared = SwiftBridge()

  @objc func evaluate(texture: MTLTexture) -> Bool {
    guard let delegate = self.delegate else {
      return false

    let rect = CGRect(x: 1, y: 2, width: 100, height: 200)

    return true

  @objc func setDelegate(callback: @escaping DelegateCallbackFunction) -> Bool {
    self.delegate = callback

    return true


using System;
using UnityEngine;
using System.Runtime.InteropServices;
using AOT;

public struct CGPoint {
    public float x;
    public float y;

public struct CGSize {
    public float width;
    public float height;

public struct CGRect {
    public CGPoint origin;
    public CGSize size;


public class UnityBridge : MonoBehaviour {

    #region Declare external C interface    

    private static extern int _vision_detectObjectsIn(IntPtr texture);

    delegate bool ObjectDetectedCallback(ref CGRect rect);
    private static extern void _vision_setDelegate(ObjectDetectedCallback callback);

    private static bool delegateMessageReceived(ref CGRect rect) {
        Debug.Log("Message received: " + rect.origin.x);
        return true;
    // #endif

    public void initializeDelegate() {
        if (Application.platform == RuntimePlatform.IPhonePlayer) {

   #region Wrapped methods and properties
   public void EvaluateTexture(IntPtr texture) {

    if (texture == IntPtr.Zero) {
      Debug.LogError("[Texture] Pointer to buffer is null.");

    bool success;


   #region Singleton implementation
   private static WeRDetectorUnity _instance;
   public static WeRDetectorUnity Instance {
       get {
           if (_instance == null) {
               var obj = new GameObject("WeRDetectorUnity");
               _instance = obj.AddComponent<WeRDetectorUnity>();
           return _instance;

   void Awake() {
       if (_instance != null) {



The message receive print in Unity does not return a 1 as it should but rather a strange exponent small number. Any idea??

1 Answers

chandresh patel On

You need to create struct for pass parameter its you can use parameters on multiple time and also access in main class.

struct Location {
  let latitude:"latitude"
  let longitude: "longitude"