ios -Unity3D的EasyAR集成到已經有項目中。

 

 近期 在作AR這一塊,用EasyAR集成到iOS端,因爲如今到項目已經上線,下一版本要作一個AR功能,因而迫於需求須要,本身研究和翻閱讀好多集成到資料。app

經過整理分出幾個重要到模塊,其中在這裏指出Xcode9版本確實好坑,建議棄坑,該用稍微好點到版本Xcode9.1.dom

 

一模塊.Unity3D導出iOS項目(UD,表示)。socket

二模塊.從UD取出重要到三個文件。ide

三模塊.新建一個iOS項目(ID,表示)atom

四模塊.在ID配置Unity3D的環境spa

五模塊.在ID建立Unity3D的控制器文件及代碼3d

 

開始演示:code

一模塊.Unity3D導出iOS項目(UD,表示)。orm

1.在搞好Unity的代碼開發後就能夠倒出iOS版本了(若是沒有AR項目,能夠到EasyAR去找dome來作)。server

2.導出到相關配置如標,按裏面的配置好就好,注意【’容許使用相機?‘,要寫,否則導出iOS後運行會崩潰】:(圖是取來別人的圖)

 

二模塊.從UD取出重要到三個文件。

 1.三個目錄,Classes,Libraries,Data。

 

三模塊.新建一個iOS項目(ID,表示)

 1.引用UD項目裏的三個文件,並集成到ID項目裏。

 2.這裏須要注意的是,Classes和Libraries目錄做爲Group引用,切記不要勾選copy。

 3.而Data目錄不須要參與編譯,做爲folder引用進來便可。

文件結構以下:(能夠不要建立文件夾放置,按照UD項目的結構來作)

 

四模塊.在ID配置Unity3D的環境

 1.關閉bitcode。新版的Unity已經支持Bitcode但EasyAR並不支持,不關閉沒法正常編譯。如圖:

 

2.修改Linking -> Other Linker Flags選項,添加參數 -weak_framework CoreMotion -weak-lSystem

3.修改頭文件搜索目錄,如圖:

結構如:

"$(SRCROOT)/項目名稱/Classes"

"$(SRCROOT)/項目名稱/Libraries"

"$(SRCROOT)/項目名稱/Libraries/libil2cpp/include"

"$(SRCROOT)/項目名稱/Classes/Native"

"$(SRCROOT)/項目名稱"

"$(SRCROOT)" 

 

4.修改庫搜索目錄,如圖:

結構如:

"$(SRCROOT)/項目名稱/Libraries"

"$(SRCROOT)/項目名稱/Libraries/Plugins/iOS"

"$(SRCROOT)/項目名稱"

 

 

5. 修改LLVM - Custom Complier Flags -> Other C Flags選項,添加兩個參數: -DINIT_SCRIPTING_BACKEND=1 和 -DRUNTIME_IL2CPP=1

 

6.修改LLVM - Language -> C Language Dialect選項,選擇C99

 

 

7.修改LLVM - Language - C++ -> C++ Language Dialect選項,選擇 C++11

 

 8.添加三項自定義設置

  • MTL_ENABLE_DEBUG_INFO -> NO
  • UNITY_RUNTIME_VERSION -> 2017.1.1f1(當前你的Unity3d版本號,請自行替換)
  • UNITY_SCRIPTING_BACKEND -> il2cpp

 

 

9.新建一個PCH文件,並修改Precompile Prefix Header爲YES,關聯pch文件路徑。此處新建文件名爲 PrefixHeader.pch。

 

10.添加工程依賴(注意三個Optional)

 

五模塊.在ID建立Unity3D的控制器文件及代碼

  1.ID項目中,將Classes/下的main.mm文件裏面的內容,複製所有到集成項目的Supporting Files/下的main.m文件中,而後刪除Classes/main.mm,而且把文件後綴改爲.mm。而且按照下圖對內容進行修改

2.修改 UnityAppController文件

改以前:

改以後:(‘delegate.unityController’的unityController,是以後要建的自定義文件,用來處理AR界面處理的,不明白能夠無論)

3.新建一個UnityController文件繼承於UnityAppController用來處理AR界面處理(注意變成C++混編文件【把.m文件變成.mm文件】)

 


UnityController.mm文件以下:

 

//  Created by XY IOS on 2017/11/18.

//  Copyright © 2017年 陳詩友. All rights reserved.

//

 

#import "UnityController.h"

 

 

#import "UnityAppController.h"

#import "UnityAppController+ViewHandling.h"

#import "UnityAppController+Rendering.h"

 

#import "DisplayManager.h"

#import "UnityView.h"

 

#include "RegisterMonoModules.h"

#include "RegisterFeatures.h"

#include <csignal>

 

@interface UnityController()

 

@property (nonatomic, assign) BOOL isInitUnity;

 

@end

 

 

@implementation UnityController

 

+ (instancetype)instance

{

    return (UnityController *)[[UIApplication sharedApplication]valueForKeyPath:@"delegate.unityController"];

}

 

 

- (instancetype)init

{

    self = [super init];

    if (self) {

        self.isInitUnity = NO;

        // 註冊Unity的事件

        [[NSNotificationCenter defaultCenteraddObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];

        [[NSNotificationCenter defaultCenteraddObserver:self selector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];

        [[NSNotificationCenter defaultCenteraddObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];

        [[NSNotificationCenter defaultCenteraddObserver:self selector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotification object:nil];

        [[NSNotificationCenter defaultCenteraddObserver:self selector:@selector(appDidReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];

        

    }

    return self;

}

- (void)appWillEnterForeground:(NSNotification *)notification {

    [self applicationWillEnterForeground:[UIApplication sharedApplication]];

}

 

- (void)appDidBecomeActive:(NSNotification *)notification {

    if (nil == self.unityView) {

        return;

    }

    [self applicationDidBecomeActive:[UIApplication sharedApplication]];

}

 

- (void)appWillResignActive:(NSNotification *)notification {

    [self applicationWillResignActive:[UIApplication sharedApplication]];

}

 

- (void)appWillTerminate:(NSNotification *)notification {

    [self applicationWillTerminate:[UIApplication sharedApplication]];

}

 

- (void)appDidReceiveMemoryWarning:(NSNotification *)notification {

    [self applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]];

}

 

 

- (UIView *)playView

{

    return self.unityView;

}

 

static const int constsection = 0;

void UnityInitTrampoline();

void initMain() {

    @autoreleasepool

    {

//        UnityInitTrampoline();

//        UnityInitStartupTime();

        UnityInitTrampoline();

        UnityInitRuntime(0NULL);

        

        

        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);

        

    }

}

 

- (void)initUnity {

    

    if (!self.isInitUnity) {

        

        initMain();

        

        

        if ([UIDevice currentDevice].generatesDeviceOrientationNotifications == NO)

            [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

        

        UnityInitApplicationNoGraphics([[[NSBundle mainBundlebundlePathUTF8String]);

        [self selectRenderingAPI];

        [UnityRenderingView InitializeForAPIself.renderingAPI];

        _window = nil;

        _unityView      = [self createUnityView];

        

        

        [DisplayManager Initialize];

        _mainDisplay    = [DisplayManager Instance].mainDisplay;

        [_mainDisplay createWithWindow: _window andView: _unityView];

        

        [super applicationDidBecomeActive:[UIApplication sharedApplication]];

        

        self.isInitUnity = YES;

    }

    

}

 

- (void)pauseUnity {

    

    //[self applicationWillResignActive:[UIApplication sharedApplication]];

    UnityPause(1);

}

 

- (void)startUnity {

    

    //[self applicationDidBecomeActive:[UIApplication sharedApplication]];

    UnityPause(0);

}

 

- (BOOL)isPaused {

    if (UnityIsPaused() == 1) {

        return YES;

    }

    else {

        return NO;

    }

}

@end

 

 

4.在ViewController 文件建立一個(sbtn)按鈕[驅動AR], 一個view[AR容器],要注意一點要在AppDelegate.m文件初始化UnityController

 

#import "ViewController.h"

 

 

#import "UnityController.h"

 

 

@interface ViewController ()

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    [self initUI];

    // Do any additional setup after loading the view, typically from a nib.

}

 

- (void)initUI

{

//    self.view.backgroundColor = [UIColor whiteColor];

    UIButton *sbtn = [UIButton buttonWithType:UIButtonTypeCustom];

    sbtn.frame = CGRectMake((CGRectGetMaxX(self.view.frame) - 60 ) / 2, 150, 60, 40);

    sbtn.backgroundColor = [UIColor purpleColor];

    [sbtn setTitle:@"AR開始" forState:UIControlStateNormal];

    [sbtn addTarget:self action:@selector(Actions) forControlEvents:UIControlEventTouchDown];

    [self.view addSubview:sbtn];

    

//    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];

//    button1.frame = CGRectMake((CGRectGetMaxX(self.view.frame) - 60 ) / 2, 150 + 40, 60, 40);

//    [button1 setTitle:@"AR暫停" forState:UIControlStateNormal];

//    [self.view addSubview:button1];

//    button1.backgroundColor = [UIColor redColor];

//    [button1 addTarget:self action:@selector(clickHandler1:) forControlEvents:UIControlEventTouchUpInside];

 

    

    // 供Unity顯示的View

//    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(sbtn.frame) + 50, CGRectGetWidth(self.view.frame), 400)];

    UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];

    [view setBackgroundColor:[UIColor grayColor]];

    [view setTag:22];

    view.hidden = YES;

    [self.view addSubview:view];

    

 

    

 

}

- (void) clickHandler1:(id)sender

{

    if ([[UnityController instance] isPaused]) {

        [[UnityController instance] startUnity];

    }

    else {

        [[UnityController instance] pauseUnity];

    }

}

 

 

- (void)Actions

{

    NSLog(@"ar");

//    self.unityController = [[UnityController alloc]init];

    [self.view viewWithTag:22].hidden = NO;

    [[UnityController instance]initUnity];

    [UnityController instance].playView.frame = [self.view viewWithTag:22].bounds;

    [[self.view viewWithTag:22addSubview:[UnityController instance].playView];

 

//    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

 

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

 

@end

 

5.在AppDelegate.m文件初始化UnityController

 

7.問題收集

(1)在使用統一攝像頭的時候黑屏

問題表現爲,在使用Unity打包出來的項目運行是正常的,可是集合到現有項目的時候,攝像頭顯示區域是黑屏。錯誤碼是:EasyAR is running on an unsupported graphics device of type -4
解決的方法:

 

運行結果:

 

 

相關文章
相關標籤/搜索