近期 在做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后运行会崩溃】:(图是取来别人的图)

二模块.从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 defaultCenter] addObserver:self selector:@selector(appDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];

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

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

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

[[NSNotificationCenter defaultCenter] addObserver: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(0, NULL);

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 mainBundle] bundlePath] UTF8String]);

[self selectRenderingAPI];

[UnityRenderingView InitializeForAPI: self.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:22] addSubview:[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
解决的方法:

运行结果:

ios -Unity3D的EasyAR集成到已经有项目中。的更多相关文章

  1. 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结

    将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...

  2. React-Native集成到已有项目中的总结

    安装Python 从官网下载并安装python 2.7.x(3.x版本不行) 安装node.js 从官网下载node.js的官方V6.X.X版本或更高版本.安装完成后检测是否安装成功:node -v ...

  3. 【开发工具】-- IDEA集成Git在实际项目中的运用

    1.企业实际项目中Git的使用 在实际的企业项目开发中,我们一般Java的项目在公司都有自己的局域网代码仓库,仓库上存放着很多的项目.以我工作过的公司如华为的项目,一般是存放在企业内部的CodeHub ...

  4. ZXingObjC 64位 集成到自己的项目中(xcode 6.4)

    参考  http://www.cocoachina.com/bbs/read.php?tid-280058-page-1.html 楼主发的DEMO中 ZXingObjC 支持64位  但是是以项目形 ...

  5. 集成activiti到现有项目中

    1.在lib中添加相关的jar包 2.找到一个activiti.cfg.xml,若是想用现有的数据库需要配置 <?xml version="1.0" encoding=&qu ...

  6. 四、spring集成ibatis进行项目中dao层基类封装

    Apache iBatis(现已迁至Google Code下发展,更名为MyBatis)是当前IT项目中使用很广泛的一个半自动ORM框架,区别于Hibernate之类的全自动框架,iBatis对数据库 ...

  7. iOS图表库Charts集成与使用

    Charts是一个很优秀的图表库,它支持Android.iOS.tvOS和macOS,这样使用起来,可以节省学习成本,可以从GitHub上了解更多信息.本文记录在iOS项目上的集成与使用. Chart ...

  8. iOS原生项目中集成React Native

    1.本文的前提条件是,电脑上已经安装了CocoaPods,React Native相关环境. 2.使用Xcode新建一个工程.EmbedRNMeituan [图1] 3.使用CocoaPods安装Re ...

  9. iOS实用技能扩展-集成支付宝

    前奏 现在随着移动开发的快速发展,移动支付变得越来越流行与必不可少.最近做了一个关于支付宝支付功能的应用,在使用支付宝的过程中,遇到一些不必要的弯路,因此,写了这篇文章总结一下关于iOS中如何开发使用 ...

随机推荐

  1. java基本的要点

    我想告诉大家的不是什么java基本要点,只是对初学者的一点忠告,本人是从八维学校亲身经历过的学生,要想学好并且快速了解java,那你首先必须有英语底子,没有英语底子,几个单词都不会的,我觉得还是放弃学 ...

  2. jsp 四大域范围

     JSP中四种作用域的不同 作用域规定的是变量的有效期限. 1.如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里. 从把变量放到pageCont ...

  3. webpackJsonp is not defined

    解决方法公共模块放前面

  4. Telerik RadGridView动态增删行及行列操作

    最近使用一直使用第三方控件Telerik,版本 2011 Q1,一直使用显示控件RadGridView,使用起来比DataGird好使, 也发现有控件问题. 1.增行 RadGridView中使用Be ...

  5. django集成celery之callback方式link_error和on_failure

    在使用django集成celery进行了异步调度任务之后,如果想对失败的任务进行跟踪或者告警,怎么做? 这里提供一个亲测的方法. 1.任务callback 假如你想在任务执行失败的时候,打印错误信息并 ...

  6. java 静态代码块 代码块 构造函数 静态成员变量 成员变量的初始化顺序

    没有父类的情况 1,静态代码块-->静态成员变量-->成员变量(实例属性)-->代码块-->构造函数 2, 静态代码块 和 静态成员变量 只会初始化一次 有父类的情况 1,父类 ...

  7. 构造函数,This关键字

    构造函数: 即构建创造对象时调用的函数.在new的时候自动执行,给对象进行初始化.创建对象都必须要通过构造函数初始化.(有参和无参) 一个类中如果没有定义过构造函数,那么类中会有一个默认的空参数构造函 ...

  8. win10 uwp iot

    这篇文章主要译: https://msdn.microsoft.com/magazine/mt694090 有很多都是胡说,随便喷,但我不会理. https://blogs.msdn.microsof ...

  9. win10 + python3.6 + VSCode + tensorflow-gpu + keras + cuda8 + cuDN6N环境配置

    写在前面的话: 再弄这个之前,我对python也好,tensorflow也好几乎是0认知的,所以配置这个环境的时候,走了不少弯路,整整耗费了一个星期的时间才搭配完整这个环境,简直了...然而最气的是, ...

  10. ADO.NET知识点

    今天复习到了ADO.NET,就把他们的知识梳理总结出来 ADO.NET 是一组向 .NET 程序员公开数据访问服务的类.提供了对各种关系数据.XML 和应用程序数据的访问. 所有的数据访问类位于Sys ...