美文网首页unityUnity跨平台技术分享
Unity3D与iOS交互1(Unity里调用iOS原生)

Unity3D与iOS交互1(Unity里调用iOS原生)

作者: Sam_xing | 来源:发表于2017-04-20 17:07 被阅读770次

此篇文章基于Unity version 5.3.6p6 与Xcode7.3。

在项目开发过程中,因为Unity3D打包之后默认都是只能用真机运行。其实Unity3D打包的项目也是可以用模拟器运行的,只是需要改下配置。

一、Unity3D打包后iOS如何使用模拟器 

(如果真机运行,不需要模拟器忽略此处,直切跳转到二。暂时没有研究如何打包后同时使用真机和模拟器, 可以分开打包)

具体步骤如下:

1.打开Unity3D项目,点击菜单栏File选项,然后点击Build Settings (快捷键Command+Shift+B),点击Player Settings进入配置界面,如图

找到最下面Other Settings设置里面的Target SDK (不同的Unity3D版本可能不同,有的是SDK Verson)。这里默认的是Device SDK,既真机状态。我们想要在模拟器下,此处选择Simulator SDK。然后就可以打包了。(注:选项Target Device 可以选择我们需要运行的设备,默认是iPhone+iPad)

2.打包成功以后,打开Unity-iPhone.xcodeproj。查看工程状态。我的工程是可以直接运行各个模拟器了。有的时候会出现如图现象,不要着急

进入工程设置Build Settings 设置界面,在Architectures目录下,找到Supported Platforms,选择iOS,这时候在工程里面就可以选择各个模拟器运行了。(这里可以选择你支持的各个平台类型)

二.Unity3D与iOS交互~~简单的传值

 Unity3D和iOS交互核心步骤如下:

             1.新建一个Unity3D项目;

            2.新建一个iOS项目,新建一个ViewController.m,ViewController.m .h文件并导入Unity3D原始项目的Plugins文件加下(Plugins具体作用,下面会详细解说),用于与Unity3D交互;

             3.打包成Xcode项目,运行测试。

1.新建一个Unity3D项目并打开。

2.新建一个iOS项目打开,创建继承于UIViewController的文件,这里我命名为UnityToIOSString。(我们也可以创建继承于NSObject)

3.在Unity3D项目的Assets文件夹下创建一个Plugins文件夹,再创建一个UnityToIOS文件夹,专门用来放原生代码文件。把UnityToIOSString文件复制到UnityToIOS文件夹中。(注:Plugins文件夹用来放native插件。它们会被自动包含进build中去。注意这个文件夹只能是Assets文件夹的直接子目录。)

4.打包成Xcode项目,接下来就是最关键的地方~~撸代码!!!!!!

1.带参数无返回值

第一步:在Xcode项目中找到我们导入的UnityToIOSString文件。编写交互函数,用来unity调取。

在Unity C#中都是用调用C语言函数,而我们在Xcode中编写代码,所以我们要加上标准C编写的Dll函数。如上图(别忘了在.h文件中写函数)。

第二步:在Unity中创建一个封装类UnityToIOS,引入在Xcode中定义的方法,方法名必须与Xcode一样。

要引入头文件usingSystem.Runtime.InteropServices;  为了[DllImport("__Internal")]。在声明实现方法的时候要加上修饰符extern,专门给外部调用的修饰符,与DllImport属性一起使用,该方法前面必须声明static。

第三步:在Unity中创建一个事件文本ButtonIOSTest,创建UI事件,调用封装方法。

保存后,基本上就完事了。但是这里面有2个小坑。1.我们在Unity中编写的代码并没有在我们导出的Xcode项目中,要重新生成Xcode项目。2.我们在第一步写的代码并没有在Unity中,我们要手动的把代码复制会Unity中的UnityToIOSString中(暂时我没有找到好的方法。如果谁有可以告诉我一声)。完成这2点之后,我们就要重新Build生成Xcode项目,这里我们最好是Append而不要用Relpace。好了,运行Xcode看效果吧。

2.带参数有返回值 -- 原理是一样的,上图。(注:有返回值的时候,因为考虑到内存管理机制的问题,在回调的时候哦要加char *MakeStringCopy (const char *string)方法)

PS: 还有无参数无返回值,无参数有返回两种函数,原理一样。

相关文章

网友评论

  • paintingStyle:你好 有问题请教下
    iOS端内部嵌入了两款AR的游戏,进入不同的场景使用 UnitySendMessage("Controller", "OpenSence",data);传递不同的参数,但是只有第一次启动他才能进入其中一个,当进入第二个发送新的消息时还是会显示第一个的游戏画面,iOS端Unity是无法关闭的,后来测试加入 UnityLoadApplication();
    Profiler_InitProfiler();
    切换偶尔是正常的,但有时候会显示错乱

    麻烦看下
    (void)showUnityWindow {

    if (_didResignActive) {

    UnityPause(false);
    }
    _didResignActive = NO;

    UnityLoadApplication();
    Profiler_InitProfiler();

    self.window.hidden =YES;
    self.unityWindow.hidden = NO;
    [self.unityWindow makeKeyWindow];
    }

    (void)hideUnityWindow {

    UnityPause(true);
    _didResignActive = YES;
    Profiler_UninitProfiler();

    self.unityWindow.hidden = YES;
    self.window.hidden = NO;
    [self.window makeKeyWindow];
    }

    发送消息代码:

    (void)wjBtnDidClicked {

    [kAppDelegate showUnityWindow];

    [self toUnityPageWithValue:@"wj"];
    }

    (void)scenesBtnDidClicked {

    [kAppDelegate showUnityWindow];

    [self toUnityPageWithValue:@"scenes"];
    }

    #pragma mark - 跳转到对应的Unity页面

    (void)toUnityPageWithValue:(NSString *)value {

    // TODO: 新增代码
    //报错SendMessage: object Controller does not have receiver for function openSence! 说明UnitySendMessage传递的对象不具备相应的方法

    const char *data = [value UTF8String];

    /**
    你那边需要打开场景的话 需要 传值给 OpenSence这个函数 通过ios给unity对象传值的方式 值有两个 "wj" 和 ”scenes“

    "Controller" "openSence" "wj 或者 scenes"
    */

    UnitySendMessage("Controller", "OpenSence",data);
    }
    Sam_xing:@paintingStyle 你好!
    // TODO: 新增代码
    //报错SendMessage: object Controller does not have receiver for function openSence! 说明UnitySendMessage传递的对象不具备相应的方法
    这里你自己不是很清楚的知道错误的原因吗?
    就是在iOS传值到unity的时候,,接受对象不对.
  • Silenceapple:没有demo呐?
    Sam_xing:@Silenceapple Swift 我没有写.
    Silenceapple:swift he unity 怎么界面交互
    Sam_xing::smiley: 不会上传.而且按照这个写就行,东西很少

本文标题:Unity3D与iOS交互1(Unity里调用iOS原生)

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