【前言】
前面两篇文章详细介绍了Unity与iOS交互的原理,相信仔细看了之后基本了解了,当然你可能需要花费好几个小时才能看明白。现在缺的就是具体的调用代码了,相信你其实可以自己一点点整理出来,但会花费不少时间趟坑,这里我们直接给出常见的交互代码示例。
【基础的交互】
传递基本数据类型和sring类型
public class Sample : MonoBehaviour
{[DllImport("__Internal")]static extern void PassIntAndString (int a, string b);
}
extern "C" void PassIntAndString(int a,const char* b)
{NSLog(@"a = %d", a);NSString *str = [NSString stringWithUTF8String:b];NSLog(@"%@", str);
}
传递基本数据类型的数组
有时候要传递的数据很多,例如一张图片的数据,这时候可能会用到数组
public class Sample : MonoBehaviour
{[DllImport("__Internal")]private static extern void SendImageData (int length, int[] data);
}
extern "C" void SendImageData(int length,int* data)
{for (int i = 0; i < length; i++) {NSLog(@"imagedata %d : %d", i, data[i]);}
}
通过MonoPInvoke让OC直接回调C#函数
一般来说,我们都会用UnitySendMessage来实现OC调用C#,即使是回调函数也一样。当然,UnitySendMessage涉及到查找transform会慢一些。如果对性能有要求,那就需要借助PInvoke来实现回调。使用UnitySendMessage时是线程安全的,使用PInvoke时要自己维护线程安全。
public class Sample:MonoBehaviour
{//回调参数必须有MonoPInvokeCallBack,而且是static的
[MonoPInvokeCallback(typeof(CallBack))]
public static int PassCallBack(string url) {}[DllImport("__Internal")]
private static extern void SetCallBack(CallBack cb );[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CallBack(string url);private void Set ()
{SetCallBack (PassCallBack);//直接把函数指针传递过去
}}
#if defined(__cplusplus)
extern "C"
{
#endif// C#设置过来的函数指针类型typedef int (*PassCallBack)(const char*); static PassCallBack callBack;void SetCallBack(PassCallBack cb) {callBack = cb;}#if defined(__cplusplus)
}
#endifvoid SetUrl(const char* url) {//回调if (callBack != nil) {callBack(url);}
}
OC传递基本数据类型的数组给C#
public class Sample:MonoBehaviour
{//回调参数必须有MonoPInvokeCallBack,而且是static的
[MonoPInvokeCallback(typeof(CallBack))]
public static int PassCallBack(int length,IntPtr data) {byte[] buffer = new byte[length]; Marshal.Copy(data, buffer, 0, length);//将数据拷贝出来
}[DllImport("__Internal")]
private static extern void SetCallBack(CallBack cb);[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CallBack(int length,IntPtr data);private void Set ()
{SetCallBack (PassCallBack);//直接把函数指针传递过去
}}
#if defined(__cplusplus)
extern "C"
{
#endif// C#设置过来的函数指针类型typedef int (*PassCallBack)(int,void*); static PassCallBack callBack;void SetCallBack(PassCallBack cb) {callBack = cb;}#if defined(__cplusplus)
}
#endifvoid SendData(int length) {//回调NSMutableArray *mutableArray = [NSMutableArray array];NSArray *array = [NSArray arrayWithArray:mutableArray];if (callBack != nil) {callBack(length,array);}
}
传递一个C#对象
传递对象有两种方式,一种是将对象序列化转为数组,相当于传递基本数据类型的数组,此处不 赘述,然后反序列化还原对象;另一种是将对象指针传递出去,类似传递函数指针。
对象指针传递
using System.Runtime.InteropServices;public class Sample {[UnmanagedFunctionPointer(CallingConvention.Cdecl)]public delegate void CallBack(IntPtr objectPtr);[DllImport("__Internal")]private static extern void PassObject(IntPtr objectPtr, CallBack callback);[MonoPInvokeCallback(typeof(CallBack))]private static void GetObject(IntPtr objectPtr) {GCHandle handle = (GCHandle) objectPtr;//从指针读取TestObjetTestObjet test = handle.Target as TestObjet;handle.Free ();}private static void Set() {TestObject test = new TestObject();IntPtr objectPtr = (IntPtr)GCHandle.Alloc (TestObject);PassObject (objectPtr, GetObject);}
}public class TestObjet
{public int a;public bool b;
}
【复杂的交互】
iOS和Unity界面跳转
两个界面跳转实际是要替换显示画面,而在iOS上画面的显示是在UIWindow中的,修改UIWindow的rootViewController即可。
将Unity作为库整合到Android或iOS中
【参考】
Unity3D与iOS的交互 - 简书
Unity - Manual: Building plug-ins for iOS
iOS 与 Unity 消息传递 (Swift 与 C#) - 简书 (jianshu.com)