赞
踩
unity版本:unity 5.4.3f1
xcode版本:xcode 8
一、导出unity项目
1.File->Build Settings->ios->Switch platform 切换为iOS平台,
2.player Settings.....(这个地方设置错误会导致导入ios工程之后出现200+错误)
3.File->Build Settings->Build(保存为xcode文件)
--------我是分割线------------
二、合并unity项目(2种方式,一是把你的工程集成到unity项目,二是把unity项目集成至你的工程)
(一),将原工程集成至unity工程
1,将原工程直接拖拽到Unity生成的工程里,在Unity的工程上进行开发。
2,将原工程的main.m文件、AppDelegate.h和AppDelegate.m文件删除,若有pch文件,也可与Unity工程中的Pch文件合并后删除(删除相关文件前请先备份,合并后请检查pch路径是否正确)。
3,此时程序的主函数入口为Classes/main.mm,AppDelegate为Classes/UnityAppController.mm,程序的pch文件为Classes/Prefix.pch。将原工程的相应代码拷贝到相对应的文件中即可。
4,因为现在程序的入口在Unity工程端,所以原工程的主界面需在Unity工程运行后(如下图,“showGameUI”方法调用之后)再添加到keyWindow上即可。
(二),将unity项目集成至原工程
1,将unity与iOS工程放置与同一根目录,将Unity工程中的`Classes`、`Data`和`Libraries`、‘MapFileParser.sh’文件夹复制到自己的工程根目录。
2,添加文件,Data 选择Create folder references,Classes和Libraries 选择Create groups。
3,在Build settings中设置Pch文件(如工程已有pch文件,请将两个pch文件合并)。选中Build Settings,在输入框中输入Prefix Header 找到设置路径的Prefix Header值,拖拽工程里的PCH文件到该输入框,点击回车键后,会显示路径,这是绝对路径,随着工程的移动,会找不到路径的,在输入框中删除工程文件夹之前的路径,用$(SRCROOT)来替换,这个值表示是相对路径,回车之后会显示设置好的相对路径,如果跟第七步骤的路径一直,标示路径设置正确。
或者,我的做法是,复制unity Classes中Pch文件中的代码添加至自己的Pch文件中,删除classes中的Pch文件
4.复制Classes中的main.mm文件中的代码,删除你的main.m中的代码,粘贴过去,删除main.mm,修改main.m为main.mm;
5,在Build Phases新建运行脚本语句Run Script
rm -rf "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"
cp -Rf "$PROJECT_DIR/Data" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Data"
6.在Build settings中设置Header Search Paths
$(SRCROOT)/Libraries/libil2cpp/include
$(SRCROOT)/Libraries/bdwgc/include
$(SRCROOT)/Classes/Native
"$(SRCROOT)/Classes"
7,在Build settings中设置Other C Flags
-mno-thumb
-DINIT_SCRIPTING_BACKEND=1
8,在Build Phases中导入以下库(这里具体请查看导出的ios工程里面的库,千万不要重复导入)
9,在Build Phases中将所有.mm文件(除了CameraCapture.mm,MetalHelper.mm,DisplayManager.mm文件)打上MRC标签。
10.编译真机运行(此时运行项目进入unity界面)
-------------------我是分割线----------------
三、在iOS工程中打开unity项目 ,(我们项目的入口为main.mm,main函数之后调用UnityAppController.mm,也就是以前项目的AppDelegate.m文件不调用,可以删除)
1.修改工程启动方式,由先启动unity视图,修改为先启动我们的ViewController
我们加入了一个myPageEnable变量,表示我们的myPage是否被启动过,如果启动做,就不再重复执行,注释掉startUnity: 改为myPageEnable:如下图。(此时,运行项目会进入我们自己的界面)
我用单利保存了当前的application 和当前的self,(用于以后点击按钮进入unity)
这样,我们就实现工程直接先启动我们的视图,其实总结一下很简单,把APP的rootViewController修改成我们的,并且停用原有Unity的相同功能代码。
2.在iOS中打开unity界面
首先,unity一旦被打开,我们是不需要彻底关闭掉的,当从unity返回我们的View 时,将unity view暂停到后台,并把window的rootviewcontroller设置为我们的rootViewController
我们已经知道,启动Unity的函数是
- (void)startUnity:(UIApplication *)application,所以重新调用这个函数即可
在我们的控制器里面点击按钮(redpacketButton是红包按钮)打开unity:
注意一点,startUnity方法只能使用一次。多次调用同样会导致应用Crash,并报错:“should not be reached at domain.c”,所以我们用restartUnity(这个方法写在UnityAppController.mm中)
3.关闭unity界面(这里有两种方法,一,调用unity中的back函数。二,我们自己写退出按钮)
值得注意的是:在extern "C"中,不能用OC的self和self.window获取到appController和window,必须使用UnityAppController对象提供的方法GetAppController()和UnityGetGLView()来获取。
3.1, 调用unity中的back函数(这个函数应和unity开发人员沟通,统一命名),调用方法:
extern "C" void back(){
//你的代码
}
3.2 自己写退出按钮
Unity View启动时在页面中初始化一个我们实现写好的关闭按钮的UIView,按钮点击事件方法和上面一样
-------------------我是分割线----------------
四。第二种集成方法
第一部分, unity3D导出Xcode项目
1.打开你的unity工程,然后点击上边菜单栏file中的build settings
2. 接着会弹出一个框, 点击switch platform 选择iOS平台,然后点击弹框的player settings... 配置参数如下图,其中Auto Graphics API的配置非常重要,如果勾选了会导致集成之后播放器一直抖动!!!
4. 配置完成后点击build, 等待完成,这个过程需要较长时间,生成工程的代码结构
5.然后把上面两个红线框圈住的文件夹和文件拷贝到我们的iOS原生项目中,合并后目录如下
第一部分导出工程的工作已经完成,这部分比较简单, 接下来,我们就开始第二大部分,也是很容易出错的地方,尤其是配置需要注意.
第二部分, 把Unity3D导出的关键代码并入原生的iOS工程
1.Unity导出的工程中的bundleId要和你本地iOS项目的id一致
2.修改bit code为NO
3.删除Main.storyboard,代码设置控制器(方便切换window,其实也可以不删除)
4.将Classes,Libraries,MapFileParser.sh拖入到项目(选中Copy items if needed,选中Create groups)
将Data拖入到项目(选中Copy items if needed,选中Create folder references)
注意:文件拖进工程的方式不完全一样,效果如下
5.添加framework(注意Optional的三个)
6.添加Header Search Paths和Library Search Paths
7.other C Flags -> -DINIT_SCRIPTING_BACKEND=1
8.添加User-Defined (UNITY_RUNTIME_VERSION版本号与导出工程的Unity版本号需要一致)
GCC_THUMB_SUPPORT
GCC_USE_INDIRECT_FUNCTION_CALLS
UNITY_RUNTIME_VERSION
UNITY_SCRIPTING_BACKEND
9.添加Run Script(这个需要注意,我们从Unity3D导出来的xcode工程里面就有这个脚本,配置成一样即可)
10.Other Linker Flags(注意添加的顺序,否则编译的时候可能出现链接库失败)
11.把Unity/Classes/Prefix.pch的代码复制到新建的pch文件, 并把classes文件夹下的pch文件删除,注意:这里的删除并不是真正的删除源文件, 只是删除引用而已!并且如果原工程已经有pch文件,则把Unity/Classes/Prefix.pch的代码添加到ios原生工程的pch文件即可,如下图:
11. 将Classes/main.mm全部内容复制到main.m 并把扩展名改为.mm
12. 修改UnityAppController.h
13.在AppDelegate.h .m中添加如下代码
到这一步基本完成了ios对Unity的调用,下面是我在做的过程中遇到的一些问题.
1."Functions that differ only in their return type cannot be overloaded"
因为objc_msgSend calls做了严格检查,改成NO就可以了,修改如下图
2.提示函数返回值不匹配问题
原因是原生的工程配置了对函数返回值做严格检查,很不幸Unity3D导出的工程有些函数返回值并不规范,所以需要把xcode的配置限制放开,兼容返回值不匹配的场景
上面就是我把Unity3D工程并入iOS工程的过程了,在做这个项目的过程中还遇到一个坑,就是播放视频模式下需要保持横屏,但是其余页面是竖屏并且不自动旋转屏幕,下一篇再跟大家分享下我的解决方案
五。Unity与iOS传值
4.1 iOS发消息给unity
// 添加这句代码,它负责向Unity传递参数;(具体参数和unity开发人员协商)
extern void UnitySendMessage(const char *, const char *, const char *);
IOS调用Unity函数需要用到UnitySendMessage方法,方法中有三个参数
UnitySendMessage("gameobject", "Method",msg);
参数一为unity脚本挂载的gameobject(可以理解为具体的unity中某个对象或者物体)
参数二为unity脚本中要调用的方法名
参数三为传递的数据,注意:传递的数据只能是char *类型
4.2 unity向iOS 传值,这个我没有用到,大家可以google 网上案例很多。
结语
最近公司开发AR红包,写出这个博客给大家作为参考。因为是初步接触unity,自己也翻越了很多资料,如果有错误,希望大家指正。后期会不断更新补全集成中遇到的各种问题。
有疑问可以给我发邮件(或者QQ),看到了必定回复:1020351736@qq.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。