目录
前言
Unity项目配置及准备
Unity导出Xcode项目
Unity调用iOS原生插件
Unity导出包含iOS原生插件的Xcode项目
前言
在移动游戏与应用开发中,Unity 强大但并非万能,尤其在面对 iOS 系统能力与原生体验需求时,原生交互能力显得尤为重要。本专栏将从零开始,一步步实践开发 Unity 与 iOS 原生通信、插件开发、UI 混合、权限与系统能力集成等核心技术。通过清晰示例与实战代码,让你真正做到:Unity 负责跨平台内容,iOS 提供原生能力,两者协同打造更专业、更高品质的移动产品。
Unity项目配置及准备
将Unity的平台切换为iOS平台。

为了方便我们调试,我们选择打包导出的使用模拟器的SDK,Player Settings里面选择Target SDK为Simulator SDK。

设置游戏的包名为com.unityleraning.unityiosplugin。(也可根据自己需求定义)

创建对应的Plugins文件夹,用来存放iOS的原生交互插件。

Unity导出Xcode项目
点击Build按钮,导出Xcode的项目。

导出Xcode的项目到指定位置后,Xcode的项目结构如下。

双击Unity-iPhone.xcodeproj文件,打开Xcode项目。并在项目结构里的Libraries文件夹下创建一个UnityiOSNativePlugin.m的文件用来实现原生的逻辑。

在UnityiOSNativePlugin.m文件里实现原生的打开iOS原生弹窗的逻辑,需要创建一个包含确认和取消两个按钮的弹窗,这样就能够在用户点击确认或者取消时获得用户的操作,并显示到Unity的界面里做后续的逻辑处理。
@interface UnityiOSNativePlugin : NSObject
void _OpeniOSNativePopup(const char* unityGameObject, const char* unityMethodName, const char* title, const char* message);
@end
@implementation UnityiOSNativePlugin
void _OpeniOSNativePopup(const char* unityGameObject, const char* unityMethodName, const char* title, const char* message)
{
NSString *unityGameObjectNameNSString = [NSString stringWithUTF8String:unityGameObject];
NSString *unityMethodNameNSString = [NSString stringWithUTF8String:unityMethodName];
NSString *titleNSString = [NSString stringWithUTF8String:title];
NSString *messageNSString = [NSString stringWithUTF8String:message];
dispatch_async(dispatch_get_main_queue(), ^{
//创建一个Alert
UIAlertController *alert =
[UIAlertController alertControllerWithTitle:titleNSString
message:messageNSString
preferredStyle:UIAlertControllerStyleAlert];
//创建一个取消按钮
UIAlertAction *cancelAction =
[UIAlertAction actionWithTitle:@"取消"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
NSLog(@"用户点击了取消");
//将取消的结果发送回Unity
UnitySendMessage(unityGameObjectNameNSString.UTF8String, unityMethodNameNSString.UTF8String, "Cancel");
}];
//创建一个确定按钮
UIAlertAction *okAction =
[UIAlertAction actionWithTitle:@"确定"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
NSLog(@"用户点击了确定");
//将确认的结果发送回Unity
UnitySendMessage(unityGameObjectNameNSString.UTF8String, unityMethodNameNSString.UTF8String, "OK");
}];
[alert addAction:cancelAction];
[alert addAction:okAction];
//显示Alert
UIViewController *rootVC = UIApplication.sharedApplication.keyWindow.rootViewController;
[rootVC presentViewController:alert animated:YES completion:nil];
});
}
@end
这里需要注意的是,我们将用来接受iOS回调消息的游戏物体名和方法名通过参数的方式传递给了iOS原生插件,当获取到用户对弹窗的操作后,我们将操作的结果通过UnitySendMessage发送到目标的游戏物体和方法。写完iOS插件后,将这个UnityiOSNativePlugin.m文件放到Unity的Plugins/iOS文件夹下。
Unity调用iOS原生插件
在Unity的场景中新建一个按钮用来打开iOS的原生弹窗,并创建一个文本用来显示用户点击弹窗取消或者确定按钮时的回调结果。

创建一个UnityiOSNativePlugin脚本,并将其挂载到名为UnityiOSNativePlugin的游戏物体上(若游戏物体名不一致会导致回调无法接受),并将打开弹窗的按钮和文本进行关联。
public class UnityiOSNativePlugin : MonoBehaviour
{
[SerializeField] private Button _openPopupiOSButton;
[SerializeField] private TMP_Text _popupResultText;
#if UNITY_IOS
[DllImport("__Internal")]
private static extern void _OpeniOSNativePopup(string unityGameObject, string unityMethodName, string title, string message);
#endif
private void OnEnable()
{
_openPopupiOSButton.onClick.AddListener(HandleOpenPopupiOSButtonPressed);
}
private void OnDisable()
{
_openPopupiOSButton.onClick.RemoveListener(HandleOpenPopupiOSButtonPressed);
}
private void HandleOpenPopupiOSButtonPressed()
{
#if UNITY_IOS
_OpeniOSNativePopup(nameof(UnityiOSNativePlugin), "HandlePopupClosed", "Hello iOS", "This is a popup from Unity!");
#endif
}
//用来接收iOS回调的方法
private void HandlePopupClosed(string result)
{
_popupResultText.text = $"Popup Result: {result}";
}
}
Unity导出包含iOS原生插件的Xcode项目
再次点击Build导出包含了iOS原生插件的Xcode项目,此时新的Xcode项目里就会包含UnityiOSNativePlugin.m文件了。

运行项目进行调试验证。

模拟器运行的界面如下。

点击Open Popup按钮后,会打开一个iOS原生的包含确认和取消两个按钮的弹窗。

点击取消,Unity会接受到回调,显示传回去的参数Cancel。

点击确认,Unity会接受到回调,显示传回去的参数OK。



