iOS中集成unity

- 說明

0.png

- 導入unity模塊

  1. unity中導出的iOS工程是這樣子的:
1.png
  1. 將Classes文件夾郎仆、Data文件夾扰肌、Libraries曙旭、MapFileParser晶府、MapFileParser.sh這五個復制到自己的iOS工程中
2.png
  1. 將Data川陆、QCAR(QCAR文件在Data->Raw里面)文件夾以以下方式添加
3.png
  1. 將Classes、Libraries以以下方式添加
4.png
  1. 添加引用庫文件
    打開從unity中導出的iOS工程鳞绕,查看其引用的庫文件猾昆,如圖所示
5.png

將上面的庫文件骡苞,添加到自己的工程中

  1. 關閉bitcode
    在build settings中關閉bitcode
  2. 在 other Linker Flags 添加
    -weak_framework CoreMotion -weak-lSystem


    14.png
  3. 在Other C Flags中添加 -DINIT_SCRIPTING_BACKEND=1,如圖所示
6.png
  1. 添加pch文件
7.png

如果項目中有多個pch文件烘苹,請將其合并成一個pch文件镣衡,再添加

  1. 在Header Search Paths 添加頭文件引用
    打開從unity導出的工程档悠,查看Header Search Paths中添加的頭文件,如圖所示
8.png

將其添加到自己工程的Header Search Paths中

  1. 在Library Search Path 中添加庫引用
    打開從unity導出的工程惰说,查看ibrary Search Path中添加的頭文件吆视,如圖所示
9.png

將其添加到自己工程的ibrary Search Path中

  1. 在user-Defined 添加
    打開從unity導出的工程啦吧, 在build settings中查看user-Defined拙寡,如圖所示
10.png

并將其添加到自己項目的 user-Defined中

11.png
  1. 添加Run Script
    打開從unity導出的工程般堆, 在build phases中查看Run Script擎宝,如圖所示:
12.png
  1. 更改main.m文件為main.mm文件浑玛。將Classes中的main.mm中的內容復制顾彰,粘貼到原來工程的main.mm中。然后刪除Classes中的main文件筋搏。
 
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#import "AppDelegate.h"
#include <mach/mach_time.h>
#include <csignal>

// Hack to work around iOS SDK 4.3 linker problem
// we need at least one __TEXT, __const section entry in main application .o files
// to get this section emitted at right time and so avoid LC_ENCRYPTION_INFO size miscalculation
static const int constsection = 0;

void UnityInitTrampoline();

// WARNING: this MUST be c decl (NSString ctor will be called after +load, so we cant really change its  value)
const char* AppControllerClassName = "UnityAppController";

int main(int argc, char* argv[])
{
  signed long long startTime = mach_absolute_time();
  @autoreleasepool
  {
      UnitySetStartupTime(startTime);
      UnityInitTrampoline();
      UnityInitRuntime(argc, argv);
      
      RegisterMonoModules();
      NSLog(@"-> registered mono modules %p\n", &constsection);
      RegisterFeatures();
      // iOS terminates open sockets when an application enters background mode.
      // The next write to any of such socket causes SIGPIPE signal being raised,
      // even if the request has been done from scripting side. This disables the
      // signal and allows Mono to throw a proper C# exception.
      std::signal(SIGPIPE, SIG_IGN);
      
      //UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);
      UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
  
  return 0;
}

#if TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR

#include <pthread.h>

extern "C" int pthread_cond_init$UNIX2003(pthread_cond_t *cond, const pthread_condattr_t *attr)
{ return pthread_cond_init(cond, attr); }
extern "C" int pthread_cond_destroy$UNIX2003(pthread_cond_t *cond)
{ return pthread_cond_destroy(cond); }
extern "C" int pthread_cond_wait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex)
{ return pthread_cond_wait(cond, mutex); }
extern "C" int pthread_cond_timedwait$UNIX2003(pthread_cond_t *cond, pthread_mutex_t *mutex,
                                             const struct timespec *abstime)
{ return pthread_cond_timedwait(cond, mutex, abstime); }

#endif // TARGET_IPHONE_SIMULATOR && TARGET_TVOS_SIMULATOR

并將main函數(shù)中的 UIApplicationMain方法修改為UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

  1. 在Classes的UnityAppController.mm中的- (void)applicationDidBecomeActive:(UIApplication*)application方法中奔脐,注釋掉[self performSelector: @selector(startUnity:) withObject: application afterDelay: 0]方法,這樣做的目的峦朗,是為防止unity的內容隨著應用的啟動波势,而啟動;
- (void)applicationDidBecomeActive:(UIApplication*)application
{
   ::printf("-> applicationDidBecomeActive()\n");

   [self removeSnapshotView];

   if (_unityAppReady)
   {
       if (UnityIsPaused() && _wasPausedExternal == false)
       {
           UnityWillResume();
           UnityPause(0);
       }
       UnitySetPlayerFocus(1);
   }
   else if (!_startUnityScheduled)
   {
       _startUnityScheduled = true;
      // [self performSelector: @selector(startUnity:) withObject: application afterDelay: 0];
   }

   _didResignActive = false;
}
  1. 修改appDelegate.h
#import <UIKit/UIKit.h>
@class UnityAppController;
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property(strong,nonatomic)UINavigationController *navi;
@property (strong, nonatomic) UIWindow *window;
@property (strong,nonatomic)UnityAppController* unityAppController;
- (void)shouldAttachRenderDelegate;
@end
  1. 將appDelegate.m修改為appDelegate.mm尺铣,并對其內容進行修改
   #import "AppDelegate.h"
#import "ViewController.h"
#import "UnityAppController.h"
@interface AppDelegate ()

@end

extern "C" void VuforiaSetGraphicsDevice(void* device, int deviceType, int eventType);
extern "C" void VuforiaRenderEvent(int marker);

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  // Override point for customization after application launch.
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  BOOL returnBool;
  if (_unityAppController == nil) {
      
      _unityAppController = [[UnityAppController alloc] init];
  }
  [_unityAppController application:application didFinishLaunchingWithOptions:launchOptions];
  
  ViewController *vc = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"viewVC"];
  self.navi = [[UINavigationController alloc] initWithRootViewController:vc];
  self.window.rootViewController=self.navi;
  [self.window makeKeyAndVisible];
  return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
  [_unityAppController applicationWillResignActive:application];
  // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
  
  [_unityAppController applicationDidEnterBackground:application];
  // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
  [_unityAppController applicationWillEnterForeground:application];
  // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
  [_unityAppController applicationDidBecomeActive:application];
  // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
  [_unityAppController applicationWillTerminate:application];
  // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (void)shouldAttachRenderDelegate
{
  UnityRegisterRenderingPlugin(&VuforiaSetGraphicsDevice, &VuforiaRenderEvent);
}
@end
  1. 在Classes的UnityAppController.h中,更改GetAppController()方法(當然要先引入#import "AppDelegate.h"
inline UnityAppController*  GetAppController()
{
  AppDelegate *dele = (AppDelegate *)[UIApplication sharedApplication].delegate;
  return (UnityAppController *)dele.unityAppController;
}
  1. 在UnityAppController.mm中重寫- (void)shouldAttachRenderDelegate方法
- (void)shouldAttachRenderDelegate  {
 AppDelegate *deleg = [UIApplication sharedApplication].delegate;
 [deleg shouldAttachRenderDelegate];
}
  1. ok,通過上面的步驟,我們就已經將unity的功能導入自己的項目中兑障,接下來做的,就是點擊按鈕逞怨,啟動unity模塊

  2. Main.storyBoard的ViewController創(chuàng)建一個UIButton,并將Storyboard ID設為“viewVC”

13.png
  1. 在ViewController.m實現(xiàn)其點擊事件(記得倒入#import "UnityAppController.h"叠赦,#import "AppDelegate.h")
 #pragma mark----打開AR-----
- (IBAction)doOpenAR:(id)sender {
   
   static bool flg=NO;
   if (flg) {//如果不是第一次啟動革砸,則之間切換window
       [GetAppController() restartUnity]; 
   }
   else//如果是第一次點擊按鈕,則需要啟動unity
   {
       [GetAppController() preStartUnity];
       [GetAppController() startUnity:[UIApplication sharedApplication]];

[UnityGetMainWindow() makeKeyAndVisible];
       flg=YES;
   }
   
}
  1. 在UnityAppController.h中申明-(void) restartUnity册踩,在UnityAppController.mm中實現(xiàn)
-(void) restartUnity
{
 _window.rootViewController=_rootController;
 [_window makeKeyAndVisible];
 [UnityGetMainWindow() makeKeyAndVisible];
 if (_didResignActive) {
     UnityPause(false);
     
     _didResignActive=NO;
 }
}
  1. 這樣效拭,我們就能啟動unity的模塊了,但是慕的,關閉或隱藏unity模塊挤渔,也需要我們操作。
  2. 我們需要在UnityAppController.mm中的- (void)startUnity:(UIApplication*)application方法里嫉父,添加一個按鈕
- (void)startUnity:(UIApplication*)application
{
 NSAssert(_unityAppReady == NO, @"[UnityAppController startUnity:] called after Unity has been initialized");

 UnityInitApplicationGraphics(UNITY_FORCE_DIRECT_RENDERING);

 // we make sure that first level gets correct display list and orientation
 [[DisplayManager Instance] updateDisplayListInUnity];

 UnityLoadApplication();
 Profiler_InitProfiler();

 [self showGameUI];
 
 
 UIButton *button=[UIButton buttonWithType:UIButtonTypeCustom];
 [button addTarget:self action:@selector(doHideenUnity) forControlEvents:UIControlEventTouchUpInside];
 button.frame=CGRectMake(0, 0, 50, 50) ;
 [button setTitle:@"退出" forState:UIControlStateNormal];
 //[button setBackgroundColor:[UIColor purpleColor]];
 [_rootView addSubview:button];
 
 [self createDisplayLink];

 UnitySetPlayerFocus(1);
}
  1. 并實現(xiàn)按鈕的點擊事件
-(void)doHideenUnity
{
 UnityPause(true);
 _didResignActive=YES;
 Profiler_UninitProfiler();
 AppDelegate *delet=[UIApplication sharedApplication].delegate;
     
     [delet.window makeKeyAndVisible];
 
}
  1. ok,完成

可能遇到了問題

  • 重復的main.mm稽鞭,記得刪除Classes文件的main.mm
  • 如果有多個pch文件引镊,記得進行合并
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末弟头,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子疹娶,更是在濱河造成了極大的恐慌伦连,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件额港,死亡現(xiàn)場離奇詭異歧焦,居然都是意外死亡,警方通過查閱死者的電腦和手機向瓷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門舰涌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人朱躺,你說我怎么就攤上這事哺徊∏颍” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵轿钠,是天一觀的道長。 經常有香客問我疗垛,道長,這世上最難降的妖魔是什么背镇? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任泽裳,我火速辦了婚禮,結果婚禮上胸囱,老公的妹妹穿的比我還像新娘瀑梗。我一直安慰自己,他們只是感情好谤职,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布亿鲜。 她就那樣靜靜地躺著,像睡著了一般陷寝。 火紅的嫁衣襯著肌膚如雪其馏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天仔引,我揣著相機與錄音褐奥,去河邊找鬼。 笑死撬码,一個胖子當著我的面吹牛,可吹牛的內容都是我干的夫否。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼汞幢,長吁一口氣:“原來是場噩夢啊……” “哼森篷!你這毒婦竟也來了?” 一聲冷哼從身側響起疾宏,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤坎藐,失蹤者是張志新(化名)和其女友劉穎哼绑,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抖韩,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡茂浮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了顽馋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡寸谜,死狀恐怖属桦,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情聂宾,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布巾陕,位于F島的核電站,受9級特大地震影響惜论,放射性物質發(fā)生泄漏馆类。R本人自食惡果不足惜弹谁,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沟于。 院中可真熱鬧植康,春花似錦、人聲如沸销睁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冗栗。三九已至,卻和暖如春隅居,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棕洋。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工掰盘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留愧捕,地道東北人申钩。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像邮偎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子禾进,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容