zoukankan      html  css  js  c++  java
  • ios -Unity3D的EasyAR集成到已经有项目中。

     近期 在做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 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 ", &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
    解决的方法:

    运行结果:

     

  • 相关阅读:
    PyQt5-关闭窗体显示提示框(窗口界面显示器上居中)-5
    PyQt5-按钮关闭窗体-4
    PyQt5-显示提示消息文本-3
    PyQt5-显示一个窗体,设置标题和图标-2
    [bzoj1053][HAOI2007]反素数ant【暴力】
    [bzoj1083][SCOI2005]繁忙的都市【MST】
    [bzoj1088][SCOI2005]扫雷Mine【乱搞】
    [bzoj1070][SCOI2007]修车【费用流】
    [bzoj1087][SCOI2005]互不侵犯King【dp】
    [bzoj4558][JLoi2016]方【容斥原理】【计数】
  • 原文地址:https://www.cnblogs.com/shenlaiyaoshi/p/7856577.html
Copyright © 2011-2022 走看看