unity版本 2017.1.1f1 Xcode版本8.2.1 (8C1002)
第一步
導(dǎo)出unity的Xcode工程(具體導(dǎo)出設(shè)置可以看文章末尾的鏈接大多數(shù)都有講到設(shè)置) 此時(shí)需要注意的是
- Bundle ID 要與你iOS項(xiàng)目保持一致(一定要一致否者可能會(huì)報(bào)很多莫名其妙的錯(cuò)誤)
第二步
將導(dǎo)出的unity工程中的以下四個(gè)文件導(dǎo)入到你的項(xiàng)目中 (如果是舊版unity可能還有一個(gè)MapFileParser文件)
注意 千萬不要選錯(cuò)導(dǎo)入方式
-
Data一定要是這樣選擇導(dǎo)入(導(dǎo)入完成后Data是藍(lán)色的文件夾)
導(dǎo)入Data.png - 另外三個(gè)選擇Creat Groups
第三步
- 照著unity導(dǎo)出的項(xiàng)目中
TARGETS ->Build Phases->Link Binary With Libraries
的依賴庫
在你自己的iOS原生項(xiàng)目中挨個(gè)添加依賴庫(已經(jīng)有了的就不用管它 千萬不要重復(fù) 也不要漏) - 如果有需要 在Build Phases中搜索.mm文件 在有需要的.mm文件上打上-fno-objc-arc(MRC標(biāo)簽);
- 然后添加腳本路徑
這里需要注意一下寫成"$PROJECT_DIR/Smart_ticket_iOS/MapFileParser.sh"
也是可以的 并且應(yīng)該以導(dǎo)入項(xiàng)目時(shí)的路徑為準(zhǔn)不是照著這個(gè)寫(具體思路見下面設(shè)置頭文件路徑)
第四步
工程配置
- 關(guān)閉bitcode。(已經(jīng)關(guān)閉的可以忽略)新版的Unity已經(jīng)支持Bitcode但你unity項(xiàng)目中的某些SDK可能并不支持,不關(guān)閉無法正常編譯。
- 添加
Build Settings
中 Header Search Paths 和 Library Search Paths
- 需要特別強(qiáng)調(diào)一下 這里有個(gè)坑 這里的路徑是你自己第二步中導(dǎo)入的四個(gè)文件的路徑,你導(dǎo)入的路徑是什么這里就寫什么 不是照著我的寫 比如文件路徑是下面這樣的
文件路徑.jpg
那么Header Search Paths就應(yīng)該添加
$(SRCROOT)/Smart_ticket_iOS/Classes
$(SRCROOT)/Smart_ticket_iOS/Classes/Native
$(SRCROOT)/Smart_ticket_iOS/Libraries/libil2cpp/include
$(SRCROOT)/Smart_ticket_iOS/Libraries
$(SRCROOT)/Smart_ticket_iOS
Library Search Paths應(yīng)該添加
$(PROJECT_DIR)/Smart_ticket_iOS/Libraries
$(PROJECT_DIR)/Smart_ticket_iOS/Libraries/Plugins/iOS
$(PROJECT_DIR)/Smart_ticket_iOS/
如果unity的文件放在項(xiàng)目根目錄 那就應(yīng)該添加
$(SRCROOT)/Classes
$(SRCROOT)/Classes/Native
$(SRCROOT)/Libraries/libil2cpp/include
$(SRCROOT)/Libraries
$(SRCROOT)
$(PROJECT_DIR)/Libraries
$(PROJECT_DIR)/Libraries/Plugins/iOS
$(PROJECT_DIR)
- 一般來說Library Search Paths不需要特別設(shè)置 你導(dǎo)入文件的時(shí)候Xcode就會(huì)自動(dòng)幫你設(shè)置好
但是如果這個(gè)設(shè)置不對(duì)會(huì)出現(xiàn)library not found for -liPhone-lib
之類的錯(cuò) - Header Search Paths如果設(shè)置不對(duì)會(huì)出現(xiàn)
'codegen/il2cpp-codegen.h' file not found
等一系列錯(cuò)誤
-
Build Settings->Other C Flags
添加-DINIT_SCRIPTING_BACKEND=1
如果無效可以嘗試把這個(gè)值移到最上面
- 如果在最后編譯成功了 但是運(yùn)行后卻在執(zhí)行unity代碼時(shí)日志打印
was compiled with optimization - stepping may behave oddly; variables may not be available
(其實(shí)這只是個(gè)警告并不是崩潰原因,這個(gè)警告是由于unity生成libiPhone-lib.a時(shí)使用了編譯優(yōu)化引起的)并崩潰可以嘗試添加-DRUNTIME_IL2CPP=1
我的項(xiàng)目就是這樣 估計(jì)是因?yàn)樘砑恿薃R 添加了以后就可以正常運(yùn)行了
- 添加自定義設(shè)置
UNITY_RUNTIME_VERSION -> xxx(你導(dǎo)出的unity項(xiàng)目中對(duì)應(yīng)的版本號(hào))
UNITY_SCRIPTING_BACKEND -> il2cpp
- 我的項(xiàng)目只添加了上面兩項(xiàng)就運(yùn)行成功了 但是其他文檔中有些提及到還要添加
MTL_ENABLE_DEBUG_INFO -> NO (這個(gè)是本來就有的修改就行)
GCC_THUMB_SUPPORT NO
GCC_USE_INDIRECT_FUNCTION_CALLS NO
- 將iOS原生項(xiàng)目中的pch文件合并到
Classes/Prefix.pch
中,并且在Build Settings->Prefix Header
中設(shè)置路徑(如果沒有就不做合并但是仍然要設(shè)置unity項(xiàng)目的pch路徑)
- 合并的時(shí)候需要注意 你原本項(xiàng)目中pch的內(nèi)容一定要放在如下部分
否則放外面的話會(huì)報(bào)unknown type name 'NSString'之類的錯(cuò)
- 復(fù)制unity項(xiàng)目文件夾Classes中的main.mm文件中的代碼(所有),刪除你原生項(xiàng)目的main.m中的代碼(除了最開始的頭文件引用部分),將復(fù)制的內(nèi)容粘貼到原生項(xiàng)目的main.m中,刪除main.mm,修改main.m為main.mm(此時(shí)如果編譯成功運(yùn)行的時(shí)候進(jìn)入的是unity頁面 沒有走我們?cè)腁ppDelegate)
- 注意編譯請(qǐng)選擇真機(jī) 集成unity后不支持模擬器
- 如果你忘記刪除main.mm會(huì)報(bào)沖突說你有兩個(gè)main
- 如果你忘記修改main.m為main.mm會(huì)報(bào)
'csignal' file not found
等錯(cuò)
- 修改啟動(dòng)函數(shù)(從我們自己的AppDelegate啟動(dòng))在修改后的main.mm中
找到
UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
將之修改為
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
此時(shí)再啟動(dòng)的話就是走我們?cè)瓉淼腁ppDelegate了
- 添加跳轉(zhuǎn)unity頁面的功能
修改Appdelegate.h
為如下樣式
#import <UIKit/UIKit.h>
#import "UnityAppController.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UIWindow *unityWindow;
@property (strong, nonatomic) UnityAppController *unityController;
- (void)showUnityWindow;
- (void)hideUnityWindow;
@end
在Appdelegate.m
中添加或修改
- (UIWindow *)unityWindow{
return UnityGetMainWindow();
}
- (void)showUnityWindow{
if (_isFirstShowUnity) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(15, 25, 20, 40);
[btn setImage:[UIImage imageNamed:@"返回"] forState:UIControlStateNormal];
[btn addTarget:self action:@selector(hideUnityWindow) forControlEvents:UIControlEventTouchUpInside];
[self.unityWindow addSubview:btn];
_isFirstShowUnity = NO;
}
[[UIApplication sharedApplication] setStatusBarHidden:YES];
UnityPause(0);
[self.unityWindow makeKeyAndVisible];
}
- (void)hideUnityWindow{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
UnityPause(1);
[self.window makeKeyAndVisible];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
在你的原有基礎(chǔ)上 return YES 之前 添加
self.unityController = [[UnityAppController alloc] init];
[self.unityController application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[self.unityController applicationWillResignActive:application];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self.unityController applicationDidEnterBackground:application];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self.unityController applicationWillEnterForeground:application];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self.unityController applicationDidBecomeActive:application];
}
- (void)applicationWillTerminate:(UIApplication *)application {
[self.unityController applicationWillTerminate:application];
}
在導(dǎo)入的unity文件夾Classes/UnityAPPController.h
中找到
記得 #import "AppDelegate.h"
inline UnityAppController* GetAppController()
{
// return (UnityAppController*)[UIApplication sharedApplication].delegate;原有的 注釋掉
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
return delegate.unityController;
---------如果上面的報(bào)錯(cuò) 換下面的寫法
return (UnityAppController*)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityController"];
}
然后在需要調(diào)用unity的地方調(diào)用方法切換成unity頁面
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate showUnityWindow];
遇到的坑
- 如果編譯報(bào)很多類似
Undefined symbols for architecture arm64:
"_glStateCacheTexEnvCombine", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheTexEnvSrc1", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheEnableTex2D", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheEnableClientStateTexCoordArray", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheTexEnvMode", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheDisableTex2D", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheEnableClientStateVertexArray", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheClientActiveTexture", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheDisableDepthTest", referenced from:
_arglDispImage in libHiARWrapper.a(gsub_es.o)
"_glStateCachePixelStoreUnpackAlignment", referenced from:
_arglPixelFormatSet in libHiARWrapper.a(gsub_es.o)
"_glStateCacheBindTexture2D", referenced from:
_arglPixelFormatSet in libHiARWrapper.a(gsub_es.o)
_arglCleanup in libHiARWrapper.a(gsub_es.o)
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
_arglPixelBufferDataUploadBiPlanar in libHiARWrapper.a(gsub_es.o)
"_glStateCacheDisableLighting", referenced from:
_arglDispImage in libHiARWrapper.a(gsub_es.o)
"_glStateCacheTexEnvSrc0", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheDisableClientStateNormalArray", referenced from:
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
"_glStateCacheActiveTexture", referenced from:
_arglPixelFormatSet in libHiARWrapper.a(gsub_es.o)
_arglCleanup in libHiARWrapper.a(gsub_es.o)
_arglDispImageStateful in libHiARWrapper.a(gsub_es.o)
_arglPixelBufferDataUploadBiPlanar in libHiARWrapper.a(gsub_es.o)
ld: symbol(s) not found for architecture arm64
這種unity里面靜態(tài)庫的錯(cuò)誤的話 可以嘗試修改Build Settings->Enable Testability
為NO 我的項(xiàng)目中就遇到了這個(gè)坑 無論怎么改都是報(bào)這個(gè)錯(cuò)(應(yīng)該是因?yàn)锳R的SDK) 后來才發(fā)現(xiàn)導(dǎo)出的項(xiàng)目中這個(gè)值是NO我的原生項(xiàng)目中這個(gè)是YES
- 如果出現(xiàn)諸如
duplicate symbol xxx in:
這種庫沖突 可以看看你是否在Build Settings->Other Linker Flag
中添加了-force_load 提及沖突的庫
把沖突的項(xiàng)刪除了
- 啟動(dòng)APP日志報(bào)錯(cuò)
Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application
并且崩潰 注意你unity里面的屏幕方向在你的項(xiàng)目設(shè)置中Target->Deployment Info->Device Orientation
是否支持 - 如果
CoreMotion
這個(gè)庫報(bào)錯(cuò),在Build Setting->Other Linker Flags
中添加-weak_framework CoreMotion -weak-lSystem
(第一次導(dǎo)入項(xiàng)目的時(shí)候遇到過一次 后來重新導(dǎo)入的時(shí)候沒遇到過 也沒添加這句項(xiàng)目也跑起來了) - 如果unity項(xiàng)目中有用到照相機(jī)麥克風(fēng)等要在info.plist中添加對(duì)應(yīng)的請(qǐng)求允許使用鍵值對(duì) 否則會(huì)崩潰
- 有些文檔提到依賴庫中
AVFoundation、CoreMotion、iAd的Status都是Optional,其他的都是Required
但是我的項(xiàng)目中沒有修改依然運(yùn)行成功,如果遇到莫名其妙的錯(cuò)誤可以嘗試 - 如果你的項(xiàng)目是ARC的那么你如果按照有些文檔中去設(shè)置了
Build Setting->C Language Dialect
為C99
會(huì)導(dǎo)致__weak Self不識(shí)別等錯(cuò)誤 事實(shí)上我沒有設(shè)置這一步也運(yùn)行成功了 就用默認(rèn)的GNU99
就可以 如果有需要為有需要的.mm文件打上MRC標(biāo)簽就好 - 有些文檔中提到的unityController里面的函數(shù)可能會(huì)跟你項(xiàng)目中有差異 注意根據(jù)實(shí)際情況使用
[_unityController Paused];
[_unityController setPaused:NO];//判斷unity控制器的狀態(tài)和改變狀態(tài)
但是我的項(xiàng)目中就沒有 取而代之的是
if (UnityIsPaused() == 1) {//判斷狀態(tài) 1暫停 0運(yùn)行中
UnityPause(0);//激活unity控制器 0激活 1暫停
}
參考文檔
http://blog.csdn.net/dylan_lwb_/article/details/51452470
http://www.lxweimin.com/p/f98bcfe09dc7
http://www.lxweimin.com/p/6ddc80cfa3fc
http://www.lxweimin.com/p/3d9ae5244d82
http://blog.csdn.net/qinqi376990311/article/details/72303053
http://blog.sina.com.cn/s/blog_48a8af640102vh2q.html