前言
网上Unity工程打包成iOS的Framework资料相当的少,笔者也是踩了各种的坑。因Unity版本的问题还是有部分差异的,如果您遇到问题先不要急,要有耐心,慢慢尝试去解决这些问题。这是笔者写的第一篇技术博客,希望可以帮助到您,如果写的不好还请给笔者些容忍度,帮助笔者修改谢谢。
参考链接
https://juejin.im/post/5d81c8d26fb9a06b1b19f6cd
工具版本
Unity版本 2018.3.0f2rw1
Xcode版本 Version 11.4
一、创建一个 Framework 工程
1. 没错就是选中它
2.更改Xcode一些配置
3. 删除armv7(因为我们Unity工程是64位不支持armv7)
二、创建一个Framework工程
1.新建一个Unity文件夹,文件夹和App..xcodeproj文件同一目录。加入工程 把Data Library Classes都拖进新建的工程, 把 Data 文件夹加入工程。选择Create folder refrences。把Library和Classes 加入工程选择Create groups。
2.去掉Library中的libil2cpp文件夹Remove Refreence(引用就可以,因为它在工程里编译不过,各种文件找不到)
3. 把MapFileParser.sh加入到根目录下,不用拖到项目中也就是和App..xcodeproj文件同一目录。在Buildphases中添加RunScript脚本"$PROJECT_DIR/MapFileParser.sh"
4. 在Build Settings中添加User DefineSetting 两项,添加
GCC_THUMB_SUPPORT NO
GCC_USE_INDIRECT_FUNCTION_CALLS NO
UNITY_RUNTIME_VERSION 2018.3.0f2rw1
UNITY_SCRIPTING_BACKEND il2cpp
5.继续在Other Linker Flags 中添加-weak_frameworkCoreMotion -weak-lSystem (-undefineddynamic_lookup选填因为我的工程报错所以要添加__mh_execute_header)
6.Header Search Paths中添加
$(PROJECT_DIR)/Unity/Classes
$(PROJECT_DIR)/Unity/Classes/Native
$(PROJECT_DIR)/Unity/Libraries/libil2cpp/include
7. Other C Flags 添加
-DINIT_SCRIPTING_BACKEND=1
-fno-strict-overflow
-DNET_4_0
-DRUNTIME_IL2CPP=1
8. Prefix Header添加Unity/Classes/Prefix.pch
9. Enable Bitcode
10. 添加系统 Framework (UnityAds.framework是来自我们unity工程里的库,不属于系统库)
三、修改Unity文件代码
1.删除引⽤DynamicLibEngineAPI-functions.h DynamicLibEngineAPI.mm(如果您工程里没有可以忽略)
2.在Classes的Unity⽂文件的DeviceSettings.mm⽂文件中 在#endif下添加return deviceUnknown;
3在UnityAppController.h⾥修改(实际测试不需要任何修改)参考了网上很多教程都是要在appDelegate里增加unityController属性,然后引用appDelegate 调用属性。由于我是SDK没法引用到appDelegate,所以我选择动态的获取并执行。但是我发现我的appDelegate并没有添加unityController这个属性,程序正常运行没有任何问题,所以我在下的截图里注释相关代码并增加log输出打印,我发现它并不为nil,而且还是无限循环被调用,我认为这里不需要做任何的修改,它有值并值为UnityAppControlle,具体下面的截图
4.向编辑确定版本号和服务地址 并在Data⽂文件下修改AppResVersionConfig.json和config.json⽂文件(不同的公司可能生成的Unity工程也不一样,如果您的工程没有这些资源文件请忽略,如果有请您设置您自己的版本和服务器地址)
5.退出游戏会切换回unity的问题修改UnityAppController+ViewHandling.mm⽂件 注释- (void)transitionToViewController:(UIViewController*)vc⽅法⾥的
6. 我们需要覆盖UnityAppController以防止Unity在加载资源时接管应用程序UI并使用框架路径而不是主程序包。覆盖didFinishLaunchingWithOptions并执行以下更改
我们要使用这种方式调用,否则Unity初始化话会因为路径找不到而崩溃
NSBundle* bundle = [NSBundlebundleForClass:[self class]];
UnityInitApplicationNoGraphics([[bundle bundlePath] UTF8String]);
也就是说我们的路径打印出来应该是这样的
/var/containers/Bundle/Application/32ECEDB3-A0C3-4AD7-9C2C-B437D70F1C0B/UnityTestDemo.app/Frameworks/UnityFramework.framework
否则framework运行时会崩溃在il2cpp::vm::MetadataCache::Initialize()所以我们要使用上面截图的路径
7.修改Unity资源文件Filesystem.mm 路径,路径不对会造成找不到资源文件卡死。正确路径
dir= AllocCString([NSBundle bundleForClass:NSClassFromString(@"UnityAppController")].bundlePath);
或dir = AllocCString([[NSBundle mainBundle].bundlePathstringByAppendingString:@"/Frameworks/UnityFramework.framework"]);
否则会因加载不出资源卡死
8. FullScreenVideoPlayer.mm 文件方法 这里也要修改路径原因和6、7一样不在多说
四、加入几个预先写好的类主要是用来调用Unity中界面类(类链接地址:https://github.com/FateOfKing/unity-export-ios-framework/tree/master/u3d-ios-framework)
我自己是参考链接的里的类简单的封装了Manager方法自己调用
五、Demo集成UnityFramework
1.添加Framework
2. 添加copy file parse
3.删除armv7和关闭BitCode(原因不多解释,因Framework不支持)
4.main.m文件 man函数修改
5. AppDelegate调用