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:

SwiftBridge

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)
    delegate(rect)

    return true
  }

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

    return true
  }
}

Unity

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

[StructLayout(LayoutKind.Sequential)]
public struct CGPoint {
    public float x;
    public float y;
};

[StructLayout(LayoutKind.Sequential)]
public struct CGSize {
    public float width;
    public float height;
};

[StructLayout(LayoutKind.Sequential)]
public struct CGRect {
    public CGPoint origin;
    public CGSize size;

}


public class UnityBridge : MonoBehaviour {

    #region Declare external C interface    
    // #if UNITY_IOS && !UNITY_EDITOR

    [DllImport("__Internal")]
    private static extern int _vision_detectObjectsIn(IntPtr texture);

    delegate bool ObjectDetectedCallback(ref CGRect rect);
    [DllImport("__Internal")]
    private static extern void _vision_setDelegate(ObjectDetectedCallback callback);

    [MonoPInvokeCallback(typeof(ObjectDetectedCallback))] 
    private static bool delegateMessageReceived(ref CGRect rect) {
        Debug.Log("Message received: " + rect.origin.x);
        return true;
    }
    // #endif
    #endregion

    public void initializeDelegate() {
        if (Application.platform == RuntimePlatform.IPhonePlayer) {
            _vision_setDelegate(delegateMessageReceived);
        }
    }

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

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

    bool success;

     #if UNITY_IOS && !UNITY_EDITOR
     _vision_detectObjectsIn(texture);
     #endif
   }
   #endregion

   #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) {
           Destroy(gameObject);
           return;
       }

       DontDestroyOnLoad(gameObject);
   }
   #endregion


}

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

0
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"
}