近期 在做AR这一块,用EasyAR集成到iOS端,由于现在到项目已经上线,下一版本要做一个AR功能,于是迫于需求需要,自己研究和翻阅读好多集成到资料。

通过整理分出几个重要到模块,其中在这里指出Xcode9版本确实好坑,建议弃坑,该用稍微好点到版本Xcode9.1.

 

一模块.Unity3D导出iOS项目(UD,表示)。

二模块.从UD取出重要到三个文件。

三模块.新建一个iOS项目(ID,表示)

四模块.在ID配置Unity3D的环境

五模块.在ID创建Unity3D的控制器文件及代码

 

开始演示:

一模块.Unity3D导出iOS项目(UD,表示)。

1.在搞好Unity的代码开发后就可以倒出iOS版本了(如果没有AR项目,可以到EasyAR去找dome来做)。

2.导出到相关配置如标,按里面的配置好就好,注意【’允许使用相机?‘,要写,不然导出iOS后运行会崩溃】:(图是取来别人的图)

unity 中的easytouch_unity 中的easytouch

 

二模块.从UD取出重要到三个文件。

 1.三个目录,Classes,Libraries,Data。

 

三模块.新建一个iOS项目(ID,表示)

 1.引用UD项目里的三个文件,并集成到ID项目里。

 2.这里需要注意的是,Classes和Libraries目录作为Group引用,切记不要勾选copy。

 3.而Data目录不需要参与编译,作为folder引用进来即可。

文件结构如下:(可以不要创建文件夹放置,按照UD项目的结构来做)

unity 中的easytouch_游戏_02

 

四模块.在ID配置Unity3D的环境

 1.关闭bitcode。新版的Unity已经支持Bitcode但EasyAR并不支持,不关闭无法正常编译。如图:

 

unity 中的easytouch_移动开发_03

2.修改Linking -> Other Linker Flags选项,添加参数 -weak_framework CoreMotion -weak-lSystem

unity 中的easytouch_xcode_04

3.修改头文件搜索目录,如图:

结构如:

"$(SRCROOT)/项目名称/Classes"
"$(SRCROOT)/项目名称/Libraries"
"$(SRCROOT)/项目名称/Libraries/libil2cpp/include"
"$(SRCROOT)/项目名称/Classes/Native"
"$(SRCROOT)/项目名称"
"$(SRCROOT)"

unity 中的easytouch_游戏_05

 

4.修改库搜索目录,如图:

结构如:

"$(SRCROOT)/项目名称/Libraries"

"$(SRCROOT)/项目名称/Libraries/Plugins/iOS"

"$(SRCROOT)/项目名称"

unity 中的easytouch_unity 中的easytouch_06

 

 

5. 修改LLVM - Custom Complier Flags -> Other C Flags选项,添加两个参数: -DINIT_SCRIPTING_BACKEND=1 -DRUNTIME_IL2CPP=1

unity 中的easytouch_iOS_07

 

6.修改LLVM - Language -> C Language Dialect选项,选择C99

 

unity 中的easytouch_游戏_08

 

7.修改LLVM - Language - C++ -> C++ Language Dialect选项,选择 C++11

unity 中的easytouch_xcode_09

 

 8.添加三项自定义设置

  • MTL_ENABLE_DEBUG_INFO -> NO
  • UNITY_RUNTIME_VERSION -> 2017.1.1f1(当前你的Unity3d版本号,请自行替换)
  • UNITY_SCRIPTING_BACKEND -> il2cpp

 

unity 中的easytouch_游戏_10

 

9.新建一个PCH文件,并修改Precompile Prefix Header为YES,关联pch文件路径。此处新建文件名为 PrefixHeader.pch。

unity 中的easytouch_iOS_11

 

10.添加工程依赖(注意三个Optional)

 

unity 中的easytouch_xcode_12

五模块.在ID创建Unity3D的控制器文件及代码

  1.ID项目中,将Classes/下的main.mm文件里面的内容,复制全部到集成项目的Supporting Files/下的main.m文件中,然后删除Classes/main.mm,并且把文件后缀改成.mm。并且按照下图对内容进行修改

unity 中的easytouch_xcode_13

2.修改 UnityAppController文件

改之前:

unity 中的easytouch_unity 中的easytouch_14

改之后:(‘delegate.unityController’的unityController,是之后要建的自定义文件,用来处理AR界面处理的,不明白可以不管)

unity 中的easytouch_unity 中的easytouch_15

3.新建一个UnityController文件继承于UnityAppController用来处理AR界面处理(注意变成C++混编文件【把.m文件变成.mm文件】)

 

unity 中的easytouch_移动开发_16

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()
 
@property, assign) BOOL isInitUnity;
 
@end
 
 
@implementation UnityController
 
+ (instancetype)instance
{
returnUnityControllerUIApplication]valueForKeyPath:@"delegate.unityController"];
}
 
 
- (instancetype)init
{
self = [super init];
if (self) {
self.isInitUnity = NO;
        // 注册Unity的事件
defaultCenter] addObserver:selfselector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotificationobject:nil];
defaultCenter] addObserver:selfselector:@selector(appWillEnterForeground:) name:UIApplicationWillEnterForegroundNotificationobject:nil];
defaultCenter] addObserver:selfselector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotificationobject:nil];
defaultCenter] addObserver:selfselector:@selector(appWillTerminate:) name:UIApplicationWillTerminateNotificationobject:nil];
defaultCenter] addObserver:selfselector:@selector(appDidReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotificationobject:nil];
        
    }
;
}
- (void)appWillEnterForeground:(NSNotification *)notification {
self:[UIApplication]];
}
 
- (void)appDidBecomeActive:(NSNotification *)notification {
if (nil == self.unityView) {
return;
    }
self:[UIApplication]];
}
 
- (void)appWillResignActive:(NSNotification *)notification {
self:[UIApplication]];
}
 
- (void)appWillTerminate:(NSNotification *)notification {
self:[UIApplication]];
}
 
- (void)appDidReceiveMemoryWarning:(NSNotification *)notification {
self:[UIApplication]];
}
 
 
- (UIView *)playView
{
.unityView;
}
 
static const int constsection = 0;
void UnityInitTrampoline();
void initMain() {
    @autoreleasepool
    {
//        UnityInitTrampoline();
//        UnityInitStartupTime();
();
(0, NULL);
        
        
();
NSLog(@"-> registered mono modules %p\n", &constsection);
();
        
        // 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 {
    
ifself.isInitUnity) {
        
initMain();
        
        
ifcurrentDevice].generatesDeviceOrientationNotificationsNO)
UIDevice] beginGeneratingDeviceOrientationNotifications];
        
([[[NSBundlemainBundle] bundlePath] UTF8String]);
self];
InitializeForAPI: self.renderingAPI];
_window = nil;
_unityViewself createUnityView];
        
        
Initialize];
Instance].mainDisplay;
createWithWindow: _windowandView: _unityView];
        
super:[UIApplication]];
        
self.isInitUnity = YES;
    }
    
}
 
- (void)pauseUnity {
    
    //[self applicationWillResignActive:[UIApplication sharedApplication]];
(1);
}
 
- (void)startUnity {
    
    //[self applicationDidBecomeActive:[UIApplication sharedApplication]];
(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 ()
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
super];
self initUI];
    // Do any additional setup after loading the view, typically from a nib.
}
 
- (void)initUI
{
//    self.view.backgroundColor = [UIColor whiteColor];
UIButtonUIButton:UIButtonTypeCustom];
frame = CGRectMake((CGRectGetMaxX(self.view.frame) - 60 ) / 2, 150, 60, 40);
purpleColor];
:@"AR开始":UIControlStateNormal];
:self:@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];
:[UIColor]];
setTag:22];
hidden = YES;
self.view addSubview:view];
    
 
    
 
}
- (void) clickHandler1:(id)sender
{
ifUnityController] isPaused]) {
UnityController] startUnity];
    }
else {
UnityController] pauseUnity];
    }
}
 
 
- (void)Actions
{
NSLog(@"ar");
//    self.unityController = [[UnityController alloc]init];
self.view viewWithTag:22].hidden = NO;
UnityController]initUnity];
instance].playView.frameself.viewviewWithTag:22].bounds;
self.viewviewWithTag:22] addSubview:[UnityControllerinstance].playView];
 
//    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
 
}
- (void)didReceiveMemoryWarning {
super];
    // Dispose of any resources that can be recreated.
}
 
 
@end

 

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

 

unity 中的easytouch_xcode_17



7.问题收集

(1)在使用统一摄像头的时候黑屏

问题表现为,在使用Unity打包出来的项目运行是正常的,但是集合到现有项目的时候,摄像头显示区域是黑屏。错误码是:EasyAR is running on an unsupported graphics device of type -4
解决的方法:



unity 中的easytouch_iOS_18

unity 中的easytouch_xcode_19

 

运行结果:

 

unity 中的easytouch_移动开发_20

 

unity 中的easytouch_unity 中的easytouch_21