美文网首页
iOS与Unity3D交互

iOS与Unity3D交互

作者: 抓鱼猫L | 来源:发表于2019-12-14 17:29 被阅读0次

    最近游戏组让配合开发一个 “在Unity中点击按钮弹出原生二维码扫码页面 -> 再把获取到的二维码信息传回给Unity” 的功能,于是我就开始了学习iOS与Unity3d交互的不归路~。

    由于对Unity不熟,导出的Xcode工程跟平时用的Xcode也有些差异,遇到了很多没遇到过的问题,只能慢慢摸索,慢慢解决。

    刚开始在网上下载下来的Xcode Demo无法在真机上运行(在模拟器上正常)、添加不了Pod,只好自己新建一个干净的Unity工程,仿照Unity Demo编写交互代码再重新导出Xcode工程,没有问题了再对接二维码扫码的功能。

    一、代码实现:


    1、Unity代码:

    添加一个C#文件,添加实现代码。

    // Unity代码

    using UnityEngine;

    using System.Collections;

    using System.Runtime.InteropServices;

    public class Test : MonoBehaviour {

        public GameObject cube;

        // DllImport这个方法相当于是告诉Unity,有一个unityToIOS函数在外部会实现。

        // 使用这个方法必须要导入System.Runtime.InteropServices;

        [DllImport("__Internal")]

        private static extern void unityToIOS ( string str );

        public string scanStatus;//二维码扫描结果

        void OnGUI(){

             // 当点击按钮后,调用外部方法

             if (GUI.Button (new Rect (100, 100, 200, 60), "跳转IOS")) {

                 // Unity调用ios函数,同时传递数据

                 unityToIOS ("Hello IOS");

             }

            //控件要写在GUI里面 可以设置一个全局str,赋值,OnGUI是每秒都会自动刷新。

           GUI.Label (new Rect (100, 200, 400, 60), scanStatus); 

        }

        // 用户取消了扫码

        void cancelScan(string str){

             scanStatus = str;

        }

        // 获取二维码成功

        void getQRSuccess(string str){

             scanStatus = @"二维码内容:" + str;

        }

        // 向右转函数接口

        void turnRight(string num){

             float f;

             if (float.TryParse (num, out f)) {// 将string转换为float,数据之间的传递只能以string类型

                 Vector3 r = new Vector3 (cube.transform.rotation.x, cube.transform.rotation.y - 10f, cube.transform.rotation.z);

                 cube.transform.Rotate (r);

             } 

    }}


    2、iOS代码:

    iOS端主要在UnityAppController.mm文件中编写代码 (创建一个LARManager.h文件并创建一些交互方法)。

    // MARK: - 直接加载unity页面

    - (void)startUnity:(UIApplication*)application{

        //新增代码

        [self showUnityPage];

        /* 隐藏了一些Unity代码 */

    }

    // MARK: - 展示Unity页面

    - (void)showUnityPage {

        if ([LARManager sharedInstance].unityIsPaused) {

            UnityPause(false);//打开Unity

            [LARManager sharedInstance].unityIsPaused = NO;

            //设置rootView为Unity界面

            self.window.rootViewController = self.rootViewController;

     }}


    iOS调用Unity:通过UnitySendMessage方法实现。

    UnitySendMessage("gameobject", "Method", msg);

    参数一为unity脚本挂载的gameobject

    参数二为unity脚本中要调用的方法名

    参数三为传递的数据,*注意:传递的数据只能是char 类型

    // MARK: - iOS传递事件给Unity ScanDelegate

    //取消扫描

    - (void)cancelScan {

        [self showUnityPage];

        UnitySendMessage("Main Camera", "cancelScan", [@"取消扫描" UTF8String]);

    }

    //获取二维码信息成功

    - (void)getQRSuccess:(NSString *)str{

        [self showUnityPage];

        UnitySendMessage("Main Camera", "getQRSuccess", [str UTF8String]);

    }

    - (void)turnRight{//右转

        const char* str = [[NSString stringWithFormat:@"10"] UTF8String];

        UnitySendMessage("Main Camera", "turnRight", str);//IOS调用Unity的方法,通过UnitySendMessage方法实现。

    }

    - (void)turnLeft{//左转

        const char* str = [[NSString stringWithFormat:@"10"] UTF8String];

        UnitySendMessage("Main Camera", "turnLeft", str);

    }


    Unity调用iOS:实现Unity的调用方法

    // MARK: - Unity传递事件给iOS (跳转到iOS界面,Unity界面暂停)

    extern "C"{

        void unityToIOS(char* str){// 对Unity中的unityToIOS方法进行实现

            NSLog(@"*************%s",str);// Unity传递过来的参数

            UnityPause(true);//暂停Unity

            [LARManager sharedInstance].unityIsPaused = YES;

            //扫码页面

            ScanController *vc = [ScanController new];

            vc.delegate = GetAppController().self;//添加代理

            GetAppController().scanVC = vc;

            // GetAppController()获取appController,相当于self; UnityGetGLView()获取UnityView,相当于_window; 点击按钮后跳转到IOS界面,设置界面为IOS界面

            GetAppController().window.rootViewController = GetAppController().scanVC;

    }}

    二、遇到的问题:


    1、在Unity中: C#脚本Test和控件Cube要建立好绑定关系,不然无效.

    2、(巨坑:浪费了我不少时间~.~)

    Xcode:打包出来没有在IOS中实现Unity定义的交互函数,运行Xcode就报错,还以为是在网上下载的demo代码有问题。

    原因:

    没有实现Unity定义的交互函数_unityToIOS

    解决:

    在 extern "C”{中实现相关函数

    3、把IOS代码拖入工程后运行__weak typeof(self) wSelf = self声明报错:

    a parameter list without types is only allowed in a function definition。

    原因:

    可能是编译器识别不了typeof关键字

    解决:

    Apple LLVM 6.1 - Language设置C Language Dialect为Compiler Default或者GNU99[-std=gnu99]

    4、继续报错

    Undefined symbols for architecture arm64: "_kCGImagePropertyExifDictionary", referenced from: -[SGQRCodeObtain captureOutput:didOutputSampleBuffer:fromConnection:] in SGQRCodeObtain.o

    原因:

    引用第三方库时是直接把代码拖进工程的,可能漏了某些文件.

    解决:

    直接用pod导入第三方库.

    5、用到了相机、相册或其他功能忘记添加访问权限配置,导致闪退

    解决:

    要在info.plist中添加访问权限配置

    三、拓展:


    1、Unity导出Xcode工程:

    下载好Unity项目并打开 -> File -> Building Setting -> iOS-> Switch Platform -> Add Open Scenes -> Player Setting -> .NET 2.0 -> Build

    a、首先在File->Build Settings

    b、选择iOS,第一次装的时候需要先下载一个iOS支持文件,下载完成后安装。

    重启unity->Build(release)

    这样就创建成功一个苹果工程了

    选择iOS后要点击Switch Platform,不然打不了iOS包

    点击player settings->Target SDK可以选择映射出来的苹果项目是运行于模拟器的还是真机的。

    2、打包上架遇坑:

    在给游戏打苹果包的时候,发现在最后一步一直显示Compiling bitcode超时

    原因:

    Enable Bitcode设置的YES,工程进行了Bitcode编译很耗时。我查看了其他工程都是设置的NO

    解决:

    Build Settings->Enable Bitcode设置为NO

    3、探索:(待完善)

    游戏端的代码更新了,可不可以做到直接在原有的Xcode工程上替换unity相关文件,而不需要每次都重新生成Xcode工程,再在新工程上重新写一遍IOS代码;

    如果必须每次都写一遍的话,那就把代码封装到工具类中,每次只需要拖入工具并改少量的代码就行。把iOS代码复用性做到最高,耦合性降到最低。

    扫码相关的内容就不细说了,可以下载我的代码 MyUnityToIOS了解 提取码:feeg。里面有Unity和Xcode两端的代码,感兴趣的可以自己下载下来慢慢看~.~

    资料

    iOS与Unity3d交互

    Unity里调用iOS原生

    Unity3D与iOS的交互

    swift-unity

    相关文章

      网友评论

          本文标题:iOS与Unity3D交互

          本文链接:https://www.haomeiwen.com/subject/kdxhnctx.html