在 Unity 项目中,游戏调用平台原生的功能是很常见的。Android 平台参考 Unity 游戏调用 Android 方法 。
在 C# 中定义 extern 方法,代码中即可直接调用此方法:
123456789101112131415
// 普通方法[DllImport("__Internal")]private static extern void func();// 以字符串当参数的方法[DllImport("__Internal")]private static extern void funcWithParam(string param);// 返回字符串的方法[DllImport("__Internal")]private static extern string getStringFunc();// 返回 int 的方法[DllImport("__Internal")]private static extern int getIntFunc();
Xcode 中在 C(.c) 或 Objective-C(.m) 中声明对应的 C 语言方法。如果是 Objective-C(.m) 文件,需要修改后缀为 Objective-C++(.mm) 。例如上述的函数:
1234
void func();void funcWithParam(char *param);char *getStringFunc();int getIntFunc();
如果是 C++(.cpp) 或 Objective-C++(.mm) 文件,需要加上 extern "C" 来声明。例如:
extern "C"
123456
extern "C" { void func(); void funcWithParam(char *param); char *getStringFunc(); int getIntFunc();}
UnitySendMessage
使用 UnitySendMessage 方法来向 Unity 发送消息。
Objective-C 代码:
const char *obj = "iOSTestCallback"; // 游戏对象的名称const char *method = "OniOSCallback"; // 对象的方法const char *msg = "msg to send"; // 要发的消息UnitySendMessage(obj, method, msg);
在 Unity 中创建一个游戏对象(GameObject)名为 iOSTestCallback ,上面挂载了 iOSTestCallback.cs 脚本,如图:
iOSTestCallback
iOSTestCallback.cs
iOSTestCallback.cs 脚本中实现 OniOSCallback 方法,方法签名必须是 void methodName(string msg) :
OniOSCallback
void methodName(string msg)
1234567
public class iOSTestCallback : MonoBehaviour{ // 回调的方法 msg 为发送的消息 public void OniOSCallback(string msg) { }}
回调是异步的,在下一帧中执行。
在 C# 中定义一个静态(static)方法,并添加 MonoPInvokeCallback 属性。然后将这个方法以函数指针的方式传递给 C 方法。
MonoPInvokeCallback
例如,C# 中代码:
1234567891011121314
delegate void MyFuncType(); // 回调函数的类型[AOT.MonoPInvokeCallback(typeof(MyFuncType))] // MyFunction 是 MyFuncType 类型的static void MyFunction() {} // 回调函数// 将 MyFuncType 类型的 func 传递给 iOS[DllImport("__Internal")]private static extern void RegisterCallback(MyFuncType func);// 调用时,将 MyFunction 作为参数传入void test(){ RegisterCallback(MyFunction);}
Objective-c 代码:
typedef void (*MyFuncType)(); // 定义一个函数指针类型void RegisterCallback(MyFuncType func) { func(); // 回调到 C#}
string
例如:返回字符串类型的方法必须是 char * 并在堆上分配内存 ,不能是 const char * ,虽然编译可以通过,但是运行时会崩溃,因为 Unity 会对返回的字符串进行释放:
char *
const char *
1234567891011
// 错误const char *getStringFunc() { return "test";}// 正确char *getStringFunc() { char *ret = (char*)malloc(sizeof(char)*128); strcpy(ret, "test"); return ret;}