Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Passing delegate callback functions from Unity to iOS native (Obj-c or Swift) plugin

Discussion in 'Scripting' started by Harrisonhough, Apr 6, 2020.

  1. Harrisonhough

    Harrisonhough

    Joined:
    May 13, 2014
    Posts:
    12
    Hey guys, as mentioned in the title I'm trying to figure out how to pass a delegate from Unity (C# script) to a custom iOS native plugin.

    The project I am working on requires the recording of depth data from iPhones depth sensor and also streaming of the live camera feed so users can preview what the camera sees (RGB feed). I have managed to get it working in terms of calling start/stop recording from Unity and I also have some messages Unity messages being triggered from the native classes using the UnitySendMessages functionality from the docs
    https://docs.unity3d.com/Manual/PluginsForIOS.html
    Code (CSharp):
    1. UnitySendMessage("GameObjectName1", "MethodName1", "Message to send");
    However, I can't use this method for passing back the video as UnitySendMessage takes in only a string parameter and I don't want to be converting the frame buffer into a string every frame, I want to instead create a delegate that sense the raw frame buffer as a UInt8 to then read in Unity and eventually write it to a texture2D to be displayed.

    So alas I need to use the delegate option (that is referenced in the link above^) and while it shows how to pass the function from Unity it doesn't show how to assign this callback in Objective-C. Please bear in mind my experience with C/Obj-c and Swift is extremely limited.

    So anybody know how I can pass and assign the delegate from a Unity C# script to then invoke it in my native .m or .swift file?
    Currently in my C# Script DepthRecorder.cs I have this (based off Unity docs link above)

    Code (CSharp):
    1. delegate void OnFrameUpdateDelegate(IntPtr textptr);
    2. [AOT.MonoPInvokeCallback(typeof(OnFrameUpdateDelegate))]
    3. static void OnFrameUpdate(IntPtr texPtr)
    4. {
    5.     Debug.Log("UPDATING CAMERA FRAMES :D ");
    6.     texture2D.UpdateExternalTexture(texPtr);
    7. }
    8. static extern void RegisterCallback(OnFrameUpdateDelegate onFrameUpdate);
    Then in my DepthRecorderBridge.mm I have this (I realize it's probably wrong as I am unsure how this type of delegate is meant to be represented in C/Obj-c)

    Code (CSharp):
    1. typedef void (*OnFrameUpdate)();
    2. public (OnFrameUpdate) onFrameUpateDelegate(UInt8 data);
    3.  
    4. ...
    5. (void) onFrameUpdate:(UInt8 data)
    6. {
    7.     OnFrameUpdateDelegate(data);
    8. }
    9. ......
    10.  
    11. void RegisterCallback(OnFrameUpdate frameUpdateCallback){
    12.     OnFrameUpdateDelegate = frameUpdateCallback;
    13. }
    Just for more information the core logic for all this native stuff is in two .swift files and connecting them to call the functions from DepthRecorderBridge.mm isn't the issue, just assigning/passing the Unity Delegate function that I can't figure out.

    Any help at all would be much appreciated!
     
    Last edited: Apr 6, 2020
  2. Harrisonhough

    Harrisonhough

    Joined:
    May 13, 2014
    Posts:
    12
    also the code in DepthRecorderBridge.mm is inside an extern "C"{} which is why it looks the way it is. This was from an article on linking xCode native plugins to Unity.
     
  3. Harrisonhough

    Harrisonhough

    Joined:
    May 13, 2014
    Posts:
    12
  4. uniLogix

    uniLogix

    Joined:
    May 24, 2015
    Posts:
    12
    jgarciakimble and Harrisonhough like this.