iOS項(xiàng)目集成unity工程

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文件)

unity文件.png

注意 千萬不要選錯(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è)置頭文件路徑)

第四步

工程配置

  1. 關(guān)閉bitcode。(已經(jīng)關(guān)閉的可以忽略)新版的Unity已經(jīng)支持Bitcode但你unity項(xiàng)目中的某些SDK可能并不支持,不關(guān)閉無法正常編譯。
  2. 添加 Build SettingsHeader Search PathsLibrary 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ò)誤
  1. 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)行了
  1. 添加自定義設(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 
  1. 將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ò)

  1. 復(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ò)
  1. 修改啟動(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了

  1. 添加跳轉(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 DialectC99會(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容