iOS项目接入集成Unity3D项目
如果你尝试做过接入集成这件事,那你一定知道,这一定是一个极度痛苦的故事。那么我们现在就让它变得简单起来……
1、正确的Unity3D项目(非常重要)
因为Unity3D现在是可以直接编译成ios项目并使用Xcode编译运行。打开unity导出项目,编译运行,看项目是否为可运行项目。
如果报错:
- MapFileParser.sh: Permission denied
- Command PhaseScriptExecution failed with a nonzero exit code
![](https://img.haomeiwen.com/i11865498/f709ff5c7d30da56.png)
解决办法:
cd 到项目根目录 为报错文件添加读写权限
执行代码 chmod +x 文件
![](https://img.haomeiwen.com/i11865498/6f166016a80c66b3.png)
2、配置原生工程
- 1 、把Unity3D导出的关键代码并入原生的iOS工程(Unity3D导出的工程中的Bundle Id要和你本地iOS项目的Bundle Id一致)
![](https://img.haomeiwen.com/i11865498/9babf27871b2e5bb.png)
-
2、修改项目配置项bit code为NO
-
3、将Classes,Libraries拖入到项目(选中Copy items if needed,选中Create groups)
将Data拖入到项目(选中Copy items if needed,选中Create folder references)
导入方式
效果如下:
![](https://img.haomeiwen.com/i11865498/bcd70be3a2618c46.png)
- 4、 添加framework
打开已可以正常运行的Unity3D项目,根据项目-General-Linked Frameworks and Libraries 添加所有的framework至工程中
![](https://img.haomeiwen.com/i11865498/f35930fc6cbc0f33.png)
特别注意、标红的framework需要选择optional
- 5、添加Header Search Paths和Library Search Paths
![](https://img.haomeiwen.com/i11865498/2499821de9d6fa3e.png)
![](https://img.haomeiwen.com/i11865498/0b43330a79d433de.png)
- 6、other C Flags -> -DINIT_SCRIPTING_BACKEND=1
![](https://img.haomeiwen.com/i11865498/de4a51e388826e01.png)
-
7、添加User-Defined (UNITY_RUNTIME_VERSION版本号与导出工程的Unity版本号需要一致)
添加
GCC_THUMB_SUPPORT ----> NO
GCC_USE_INDIRECT_FUNCTION_CALLS ----> NO
UNITY_RUNTIME_VERSION ---->2018.2.1f1(2018.2.1f1为统一开发人员要统一的版本号)
UNITY_SCRIPTING_BACKEND ----> il2cpp
![](https://img.haomeiwen.com/i11865498/bc188ff3fc4e78d0.png)
-
8、添加Run Script(这个需要注意,我们从Unity3D导出来的xcode工程里面就有这个脚本,配置成一样即可)
脚本设置
- 9、Other Linker Flags(注意添加的顺序,否则编译的时候可能出现链接库失败)
![](https://img.haomeiwen.com/i11865498/143360d4b536075f.png)
-
10、合并pch文件
把Unity/Classes/Prefix.pch的代码复制到新建的pch文件, 并把classes文件夹下的pch文件删除。
删除方式
注意:这里的删除并不是真正的删除源文件, 只是删除引用而已!
如果原工程已经有pch文件,则把Unity/Classes/Prefix.pch的代码添加到ios原生工程的pch文件即可,如下图:
![](https://img.haomeiwen.com/i11865498/0a46ca125776594c.png)
- 11、将Classes/main.mm全部内容复制到main.m 并把扩展名改为.mm
修改为先启动appdelegate
![](https://img.haomeiwen.com/i11865498/61c8d19e192c9b96.png)
//
// main.m
// DookayProject
//
// Created by momo on 2017/10/23.
// Copyright © 2017年 DookayProject. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>
static const int constsection = 0;
void UnityInitTrampoline();
// WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its value)
const char* AppControllerClassName = "UnityAppController";
int main(int argc, char* argv[])
{
UnityInitStartupTime();
@autoreleasepool
{
UnityInitTrampoline();
UnityInitRuntime(argc, argv);
RegisterMonoModules();
NSLog(@"-> registered mono modules %p\n", &constsection);
RegisterFeatures();
// iOS terminates open sockets when an application enters background mode.
// The next write to any of such socket causes SIGPIPE signal being raised,
// even if the request has been done from scripting side. This disables the
// signal and allows Mono to throw a proper C# exception.
std::signal(SIGPIPE, SIG_IGN);
//UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
return 0;
}
#if TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR
#include <pthread.h>
extern "C" int pthread_cond_init$UNIX2003(pthread_cond_t *cond, const pthread_condattr_t *attr)
{ return pthread_cond_init(cond, attr); }
extern "C" int pthread_cond_destroy$UNIX2003(pthread_cond_t *cond)
{ return pthread_cond_destroy(cond); }
extern "C" int pthread_cond_wait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex)
{ return pthread_cond_wait(cond, mutex); }
extern "C" int pthread_cond_timedwait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime)
{ return pthread_cond_timedwait(cond, mutex, abstime); }
#endif // TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR
- 12、unity随APP启动而启动
本文是将加载的iOS页面,通过一个入口跳转统一Unity页面,比如按钮点击或者是页面推送,通过切换窗口来达到目的
在AppDelegate.h .m中添加如下代码:
![](https://img.haomeiwen.com/i11865498/1763a126f0f5ee74.png)
![](https://img.haomeiwen.com/i11865498/e786461106b12b2f.png)
- 13、配置UnityAppController.h .m
添加重启方法
![](https://img.haomeiwen.com/i11865498/e647f4f07ef93b21.png)
unity启动时添加返回按钮用来回到APP
![](https://img.haomeiwen.com/i11865498/f9657e1ed10d7c52.png)
隐藏与关闭unity 窗口方法
![](https://img.haomeiwen.com/i11865498/4db7a184cb089a5f.png)
- 14、APP内启动unity
具体打开模型传值方法由Unity方提供对象和方法名
![](https://img.haomeiwen.com/i11865498/60d480bb7c964d50.png)
运行项目如遇报错
-
Permission denied: 权限报错,一般为对应文件添加读写权限即可
-
bad interpreter: Operation not permitted, 文件带有扩展属性,打开方式不正确:可cd到目录执行 xattr -d com.apple.quarantine 文件 清除扩展属性