unity版本 2017.1.1f1 Xcode版本8.2.1 (8C1002)
第一步
導(dǎo)出unity的Xcode工程(具體導(dǎo)出設(shè)置可以看文章末尾的鏈接大多數(shù)都有講到設(shè)置) 此時需要注意的是
- Bundle ID 要與你iOS項目保持一致(一定要一致否者可能會報很多莫名其妙的錯誤)
第二步
將導(dǎo)出的unity工程中的以下四個文件導(dǎo)入到你的項目中 (如果是舊版unity可能還有一個MapFileParser文件)
注意 千萬不要選錯導(dǎo)入方式
-
Data一定要是這樣選擇導(dǎo)入(導(dǎo)入完成后Data是藍(lán)色的文件夾)
- 另外三個選擇Creat Groups
第三步
- 照著unity導(dǎo)出的項目中
TARGETS ->Build Phases->Link Binary With Libraries
的依賴庫
在你自己的iOS原生項目中挨個添加依賴庫(已經(jīng)有了的就不用管它 千萬不要重復(fù) 也不要漏) - 如果有需要 在Build Phases中搜索.mm文件 在有需要的.mm文件上打上-fno-objc-arc(MRC標(biāo)簽);
- 然后添加腳本路徑
這里需要注意一下寫成"$PROJECT_DIR/Smart_ticket_iOS/MapFileParser.sh"
也是可以的 并且應(yīng)該以導(dǎo)入項目時的路徑為準(zhǔn)不是照著這個寫(具體思路見下面設(shè)置頭文件路徑)
第四步
工程配置
- 關(guān)閉bitcode。(已經(jīng)關(guān)閉的可以忽略)新版的Unity已經(jīng)支持Bitcode但你unity項目中的某些SDK可能并不支持彩郊,不關(guān)閉無法正常編譯毒坛。
- 添加
Build Settings
中 Header Search Paths 和 Library Search Paths
- 需要特別強調(diào)一下 這里有個坑 這里的路徑是你自己第二步中導(dǎo)入的四個文件的路徑,你導(dǎo)入的路徑是什么這里就寫什么 不是照著我的寫 比如文件路徑是下面這樣的
那么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的文件放在項目根目錄 那就應(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)入文件的時候Xcode就會自動幫你設(shè)置好
但是如果這個設(shè)置不對會出現(xiàn)library not found for -liPhone-lib
之類的錯 - Header Search Paths如果設(shè)置不對會出現(xiàn)
'codegen/il2cpp-codegen.h' file not found
等一系列錯誤
-
Build Settings->Other C Flags
添加-DINIT_SCRIPTING_BACKEND=1
如果無效可以嘗試把這個值移到最上面
- 如果在最后編譯成功了 但是運行后卻在執(zhí)行unity代碼時日志打印
was compiled with optimization - stepping may behave oddly; variables may not be available
(其實這只是個警告并不是崩潰原因,這個警告是由于unity生成libiPhone-lib.a時使用了編譯優(yōu)化引起的)并崩潰可以嘗試添加-DRUNTIME_IL2CPP=1
我的項目就是這樣 估計是因為添加了AR 添加了以后就可以正常運行了
- 添加自定義設(shè)置
UNITY_RUNTIME_VERSION -> xxx(你導(dǎo)出的unity項目中對應(yīng)的版本號)
UNITY_SCRIPTING_BACKEND -> il2cpp
- 我的項目只添加了上面兩項就運行成功了 但是其他文檔中有些提及到還要添加
MTL_ENABLE_DEBUG_INFO -> NO (這個是本來就有的修改就行)
GCC_THUMB_SUPPORT NO
GCC_USE_INDIRECT_FUNCTION_CALLS NO
- 將iOS原生項目中的pch文件合并到
Classes/Prefix.pch
中,并且在Build Settings->Prefix Header
中設(shè)置路徑(如果沒有就不做合并但是仍然要設(shè)置unity項目的pch路徑)
- 合并的時候需要注意 你原本項目中pch的內(nèi)容一定要放在如下部分
否則放外面的話會報unknown type name 'NSString'之類的錯
- 復(fù)制unity項目文件夾Classes中的main.mm文件中的代碼(所有)疹启,刪除你原生項目的main.m中的代碼(除了最開始的頭文件引用部分)古程,將復(fù)制的內(nèi)容粘貼到原生項目的main.m中,刪除main.mm喊崖,修改main.m為main.mm(此時如果編譯成功運行的時候進(jìn)入的是unity頁面 沒有走我們原生的AppDelegate)
- 注意編譯請選擇真機 集成unity后不支持模擬器
- 如果你忘記刪除main.mm會報沖突說你有兩個main
- 如果你忘記修改main.m為main.mm會報
'csignal' file not found
等錯
- 修改啟動函數(shù)(從我們自己的AppDelegate啟動)在修改后的main.mm中
找到
UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
將之修改為
UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
此時再啟動的話就是走我們原來的AppDelegate了
- 添加跳轉(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;
---------如果上面的報錯 換下面的寫法
return (UnityAppController*)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityController"];
}
然后在需要調(diào)用unity的地方調(diào)用方法切換成unity頁面
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate showUnityWindow];
遇到的坑
- 如果編譯報很多類似
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)庫的錯誤的話 可以嘗試修改Build Settings->Enable Testability
為NO 我的項目中就遇到了這個坑 無論怎么改都是報這個錯(應(yīng)該是因為AR的SDK) 后來才發(fā)現(xiàn)導(dǎo)出的項目中這個值是NO我的原生項目中這個是YES
- 如果出現(xiàn)諸如
duplicate symbol xxx in:
這種庫沖突 可以看看你是否在Build Settings->Other Linker Flag
中添加了-force_load 提及沖突的庫
把沖突的項刪除了
- 啟動APP日志報錯
Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application
并且崩潰 注意你unity里面的屏幕方向在你的項目設(shè)置中Target->Deployment Info->Device Orientation
是否支持 - 如果
CoreMotion
這個庫報錯挣磨,在Build Setting->Other Linker Flags
中添加-weak_framework CoreMotion -weak-lSystem
(第一次導(dǎo)入項目的時候遇到過一次 后來重新導(dǎo)入的時候沒遇到過 也沒添加這句項目也跑起來了) - 如果unity項目中有用到照相機麥克風(fēng)等要在info.plist中添加對應(yīng)的請求允許使用鍵值對 否則會崩潰
- 有些文檔提到依賴庫中
AVFoundation、CoreMotion荤懂、iAd的Status都是Optional茁裙,其他的都是Required
但是我的項目中沒有修改依然運行成功,如果遇到莫名其妙的錯誤可以嘗試 - 如果你的項目是ARC的那么你如果按照有些文檔中去設(shè)置了
Build Setting->C Language Dialect
為C99
會導(dǎo)致__weak Self不識別等錯誤 事實上我沒有設(shè)置這一步也運行成功了 就用默認(rèn)的GNU99
就可以 如果有需要為有需要的.mm文件打上MRC標(biāo)簽就好 - 有些文檔中提到的unityController里面的函數(shù)可能會跟你項目中有差異 注意根據(jù)實際情況使用
[_unityController Paused];
[_unityController setPaused:NO];//判斷unity控制器的狀態(tài)和改變狀態(tài)
但是我的項目中就沒有 取而代之的是
if (UnityIsPaused() == 1) {//判斷狀態(tài) 1暫停 0運行中
UnityPause(0);//激活unity控制器 0激活 1暫停
}
參考文檔
http://blog.csdn.net/dylan_lwb_/article/details/51452470
http://www.reibang.com/p/f98bcfe09dc7
http://www.reibang.com/p/6ddc80cfa3fc
http://www.reibang.com/p/3d9ae5244d82
http://blog.csdn.net/qinqi376990311/article/details/72303053
http://blog.sina.com.cn/s/blog_48a8af640102vh2q.html