前面两篇文章详细介绍了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)
}
#endif
void 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)
}
#endif
void 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;
//从指针读取TestObjet
TestObjet 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)