在 Unity 项目中,游戏调用平台原生的功能是很常见的。Android 平台参考Unity 游戏调用 Android 方法。
C# 调用 iOS 代码
在 C# 中定义 extern 方法,代码中即可直接调用此方法:
1 | // 普通方法 |
Xcode 中在 C(.c) 或 Objective-C(.m) 中声明对应的 C 语言方法。如果是 Objective-C(.m) 文件,需要修改后缀为 Objective-C++(.mm) 。例如上述的函数:
1 | void func(); |
如果是 C++(.cpp) 或 Objective-C++(.mm) 文件,需要加上 extern "C"
来声明。例如:
1 | extern "C" { |
iOS 调用 C# 代码
使用 UnitySendMessage
使用 UnitySendMessage
方法来向 Unity 发送消息。
Objective-C 代码:
1 | const char *obj = "iOSTestCallback"; // 游戏对象的名称 |
在 Unity 中创建一个游戏对象(GameObject)名为 iOSTestCallback
,上面挂载了 iOSTestCallback.cs
脚本,如图:
iOSTestCallback.cs
脚本中实现 OniOSCallback
方法,方法签名必须是 void methodName(string msg)
:
1 | public class iOSTestCallback : MonoBehaviour |
回调是异步的,在下一帧中执行。
使用委托
在 C# 中定义一个静态(static)方法,并添加 MonoPInvokeCallback
属性。然后将这个方法以函数指针的方式传递给 C 方法。
例如,C# 中代码:
1 | delegate void MyFuncType(); // 回调函数的类型 |
Objective-c 代码:
1 | typedef void (*MyFuncType)(); // 定义一个函数指针类型 |
iOS 提示
- 调用 iOS 原生代码是 CPU 密集型操作,应该避免在一帧内多次调用。
- C# 层建议封装 iOS 原生代码,并返回虚拟值。
- iOS 层返回的
string
类型应该是 UTF-8 编码,并在堆上分配内存。C# 会进行内存释放。
例如:返回字符串类型的方法必须是 char *
并在堆上分配内存 ,不能是 const char *
,虽然编译可以通过,但是运行时会崩溃,因为 Unity 会对返回的字符串进行释放:
1 | // 错误 |
参考链接
- Building plug-ins for iOS, docs.unity3d.com.
- 构建适用于 iOS 的插件,docs.unity3d.com。