原生iOS嵌入Unity導出的Xcode工程

  • 2019 年 10 月 8 日
  • 筆記

由於最近上有類似需求 所以這兩天研究了下。

一、準備工作

unity導出的xcode項目

二、開始倒騰

1、將Unity3D中的以下文件導入到工程目錄下

  • Data
  • Classes
  • MapFileParser.sh
  • Libraries
  • MapFileParser執行文件

注意:Data文件導入類型為Creat folde references Classes MapFileParser.sh Libraries MapFileParser執行文件 通過Creat groups導入

導入後如下圖所示

2、刪除引用

  • 刪除Libraries->libil2cpp的引用 選項為Remove Refernces
  • target -> Build Phases -> DynamicLibEngineAPI 移除。如果不移除 會報錯Undefined symbols for architecture arm64: …in … from:DynamicLibEngineAPI.o

3、設置classes->prefix.pch添加pch路徑

4、main.m操作

將classes中main.mm 中的程式碼複製到項目的main.m中 並把後綴也改為mm 並將

UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);

修改為

UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: @"AppDelegate"]);

5 修改AppDelegate

AppDelegate.h

@property (strong, nonatomic) UIWindow *window;  @property (strong, nonatomic) UIWindow *unityWindow;  @property (strong, nonatomic) UnityAppController *unityController;    -(void)StartUnity; //開啟unity  - (void)hideUnityWindow; //暫停

AppDelegate.m

#import "AppDelegate.h"  #import "SRViewController.h"  #import "UnityAppController.h"    @interface AppDelegate ()    @end    @implementation AppDelegate    -(UIWindow *)unityWindow{      UIWindow *window = UnityGetMainWindow();      return  window;  }    -(void)showUnityWindow{      UnityPause(false);  }    -(void)hideUnityWindow{      UnityPause(true);  }    -(void)StartUnity {      [_unityController applicationDidBecomeActive:[UIApplication sharedApplication]];      [self showUnityWindow];  }      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {      // Override point for customization after application launch.        self.unityController = [[UnityAppController alloc] init];      [_unityController application:application didFinishLaunchingWithOptions:launchOptions];          self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];      self.window.backgroundColor = [UIColor redColor];      SRViewController *vc = [[SRViewController alloc] init];      UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];        self.window.rootViewController = nav;      [self.window makeKeyAndVisible];        return YES;  }      - (void)applicationWillResignActive:(UIApplication *)application {      [_unityController applicationWillResignActive:application];  }      - (void)applicationDidEnterBackground:(UIApplication *)application {      [_unityController applicationDidEnterBackground:application];  }      - (void)applicationWillEnterForeground:(UIApplication *)application {      [_unityController applicationWillEnterForeground:application];  }    - (void)applicationDidBecomeActive:(UIApplication *)application {      [_unityController applicationDidBecomeActive:application];  }      - (void)applicationWillTerminate:(UIApplication *)application {      [_unityController applicationWillTerminate:application];  }

6 UnityAppController.h

inline UnityAppController* GetAppController()  {      return _UnityAppController;  }

修改為

#import "AppDelegate.h"  inline UnityAppController*  GetAppController()  {      AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;      return delegate.unityController;  }

7 調用

@implementation SRViewController    - (void)viewDidLoad {      [super viewDidLoad];      // Do any additional setup after loading the view.      self.navigationItem.title = @"123";      self.view.backgroundColor = [UIColor greenColor];          UIButton * btn = [[UIButton alloc] initWithFrame:CGRectMake(50, 400, 100, 50)];      [btn addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside];      [btn setTitle:@"開始" forState:UIControlStateNormal];      btn.tag = 1;      [self.view addSubview:btn];          UIButton * btn2 = [[UIButton alloc] initWithFrame:CGRectMake(50, 450, 100, 50)];      [btn2 addTarget:self action:@selector(test:) forControlEvents:UIControlEventTouchUpInside];      btn2.tag = 2;      [btn2 setTitle:@"結束" forState:UIControlStateNormal];      [self.view addSubview:btn2];    }    - (void)test:(UIButton *) btn{      AppDelegate *delegate = [UIApplication sharedApplication].delegate;      delegate.unityWindow.frame = CGRectMake(0, 0, 100, 200);        if (btn.tag == 1) {          [self.view addSubview:delegate.unityWindow];          delegate.unityWindow.hidden = NO;          [delegate StartMyUnity];      }else {          [delegate hideUnityWindow];          delegate.unityWindow.hidden = YES;      }    }

三、添加Framework以及Run Script

添加這兩項的時候注意和unity的工程中保持一致

  • Frameworkork 注意事項: 注意Status是Required還是Optional
  • libiconv.2.dylib 通過 Add Other -> command+shift+G 搜索/usr/lib 找到libiconv.2.dylib添加

四、其他重要設置

  • Enable BitCode = NO;
  • Header/Library Search Paths 和unity保持一致
  • Framework Search Paths 和unity保持一致
  • Other linker Flags 和unity保持一致
    • all_load 如果項目中有這個 記得刪除 和unity不兼容
  • Supported Platforms 根據unity導出項目保持一致 最好真機
  • Other C Flags、Other C++ Flags 和untiy保持一致
  • C Language Dialect 保持一致
  • 添加User-Defined (target->Build Settings -> Leveles右側的加號)
    • GCC_THUMB_SUPPORT = NO
    • PROVISIONING_PROFILE
    • UNITY_RUNTIME_VERSION = unity版本號
    • UNITY_SCRIPTING_BACKEND = il2cpp