美文网首页AR/VR/MR
最新:iOS 集成Unity AR

最新:iOS 集成Unity AR

作者: No_longer_xie | 来源:发表于2018-09-26 17:19 被阅读173次

最近接到一个需求,要接入AR,给了个Vuforia官网地址,还有AR开发部们同事给的demo(需求以demo为主),就直接开干,查了iOS原生接入Unity的资料,还是遇到了很多问题,在此总结记录一下。

先看效果: 首页 AR扫描后视频播放

目录

配置依赖
Demo封装
问题汇总

配置依赖

首先,我们拿到的demo结构是这样的:


demo目录
    1. 将 Classes 和 Libraries 文件夹,以及Framework文件夹中的 Vuforia.framework 拖入工程,按下图方式: 导入Classes,Libraries及Vuforia.framework

      -------------------------------------------------->>>

    1. 将 Data 文件夹拖入工程,按下图方式: 导入Data

      -------------------------------------------------->>>

    1. 结果是这样的(注意文件夹的路径,导入 Header Search Paths按此参照): 拖入后

注:需将 Data / Raw 文件夹内的Vuforia文件夹按步骤二添加到如下位置,否则会扫描无反应:


Vuforia

-------------------------------------------------->>>

  • 4.将 Classes 文件夹 main.mm 内容复制到自己项目(ARTest)中的 main.m 中 ,然后ARTest的 main.m 后缀改为 main.mm,删除 Classes 文件夹中的 main.mm (Move To Trash)有报错先忽略, 代码如下图:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#include "RegisterMonoModules.h"
#include "RegisterFeatures.h"
#include <csignal>

static const int constsection = 0;

void UnityInitTrampoline();

const char* AppControllerClassName = "UnityAppController";
int main(int argc, char * argv[]) {
    
    @autoreleasepool {
        UnityInitStartupTime();
        UnityInitTrampoline();
        
        UnityInitRuntime(argc,argv);
        RegisterMonoModules();
        RegisterFeatures();
        
        std::signal(SIGPIPE, SIG_IGN);
        
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

-------------------------------------------------->>>

    1. 在build Setting --> other Link Flags 下做如下修改:
 -weak_framework CoreMotion -weak-lSystem
other Link Flags

-------------------------------------------------->>>

    1. 在build Setting --> Header Search Paths 下做如下修改:
"$(SRCROOT)/ARTest/Unity" 
"$(SRCROOT)/ARTest/Unity/Classes"
"$(SRCROOT)/ARTest/Unity/Classes/Native"
"$(SRCROOT)/ARTest/Unity/Libraries"
"$(SRCROOT)/ARTest/Unity/Libraries/libil2cpp/include"
                  (不同项目需要按照文件在工程中的路径来确定,本次路径参照步骤三图片所示路径)
如图所示: Header Search Paths

-------------------------------------------------->>>

    1. 在build Setting --> Other C Flags 做如下修改:
-DINIT_SCRIPTING_BACKEND=1 -fno-strict-overflow -DRUNTIME_IL2CPP=1
如图所示: Other C Flags

-------------------------------------------------->>>

  • 8.在build Setting --> Precompile Prefix Header做如下修改:如图所示: precompile prefix header
注:若ARTest项目有pch 文件,需合并pch 文件,将Classes内的prefix.pch 内容全部拷贝到本项目中的pch 中,否则编译会报错,如图: PCH文件合并

-------------------------------------------------->>>

  • 9.在build Setting 做如下操作: Add-user-defined

    加入如下参数:

GCC_THUMB_SUPPORT:NO 
GCC_USE_INDIRECT_FUNCTION_CALLS:NO 
UNITY_RUNTIME_VERSION:2018.2.3f1  <--这个值可能不一样,根据自己unity-demo来 
UNITY_SCRIPTING_BACKEND: il2cpp
结果: Add-user-defined
  • 10 build Setting --> bitcode关闭
  • 11 添加依赖库,根据demo 来:


    依赖库,根据demo来

Demo封装(以上编译成功再做如下操作)

#import <UIKit/UIKit.h>
@class DTPUnityController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;
@property (nonatomic , strong)UIWindow *unityWindow;
@property (nonatomic, strong) DTPUnityController *unityController;
- (void)showUnityWindow;
- (void)hideUnityWindow;

@end

AppDelegate.mm:

#import "AppDelegate.h"
#import "DTPUnityController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    _unityController = [[DTPUnityController alloc]init];
    return YES;
}

#pragma mark ---------------unity开启与隐藏
- (UIWindow *)unityWindow
{
    if (!_unityWindow) {
        if (!UnityGetMainWindow()) {
            _unityWindow = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
        }else{
            _unityWindow = UnityGetMainWindow();
        }
    }
    return _unityWindow;
}
- (void)showUnityWindow
{
    [self.unityWindow makeKeyAndVisible];
}

- (void)hideUnityWindow
{
    [self.window makeKeyAndVisible];
    [self.unityController pauseUnity];
}

@end
  • 2.新建一个类 DTPUnityController 继承自 UnityAppController 以下是 .h 内容:
#import "UnityAppController.h"

@interface DTPUnityController : UnityAppController

+ (instancetype)instance;

- (void)initUnity;

- (void)pauseUnity;

- (void)startUnity1;

- (BOOL)isPaused;

@end

.m 内容:

#import "DTPUnityController.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>
#import "AppDelegate.h"

@interface DTPUnityController()

@property (nonatomic, assign) BOOL isInitUnity;

@end

@implementation DTPUnityController

+ (instancetype)instance {
    AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    return 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 UnityInitTrampoline();

- (void)initUnity {
     AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
    if (!self.isInitUnity) {
        
        [super applicationDidBecomeActive:[UIApplication sharedApplication]];
        
        UnityInitApplicationNoGraphics([[[NSBundle mainBundle] bundlePath] UTF8String]);
        [self selectRenderingAPI];
        [UnityRenderingView InitializeForAPI: self.renderingAPI];

        _window = delegate.unityWindow;
        _unityView      = [self createUnityView];
        
        [DisplayManager Initialize];
        _mainDisplay    = [DisplayManager Instance].mainDisplay;
        [_mainDisplay createWithWindow: _window andView: _unityView];
        
        [self createUI];
        [self preStartUnity];
        self.isInitUnity = YES;
        
        _unityView.back = ^{
            [delegate hideUnityWindow];
        };

    }else{
        [self startUnity1];
    }
     [delegate showUnityWindow];
}

- (void)pauseUnity {
    UnitySendMessage("ARCamera", "Exit", "");  // 调Unity方法 退出模型 (与unity交互)
    UnityPause(1);
}

- (void)startUnity1 {
    UnityPause(0);
}

- (BOOL)isPaused {
    if (UnityIsPaused() == 1) {
        return YES;
    }
    else {
        return NO;
    }
}

-(void)applicationDidFinishLaunching:(UIApplication *)application{
    
}

- (void)appWillEnterForeground:(NSNotification *)notification {
    [super applicationWillEnterForeground:[UIApplication sharedApplication]];
}

- (void)appDidBecomeActive:(NSNotification *)notification {
    if (nil == self.unityView) {
        return;
    }
    [super applicationDidBecomeActive:[UIApplication sharedApplication]];
}

- (void)appWillResignActive:(NSNotification *)notification {
    [super applicationWillResignActive:[UIApplication sharedApplication]];
}

- (void)appWillTerminate:(NSNotification *)notification {
    [super applicationWillTerminate:[UIApplication sharedApplication]];
}

- (void)appDidReceiveMemoryWarning:(NSNotification *)notification {
    [super applicationDidReceiveMemoryWarning:[UIApplication sharedApplication]];
}


@end
    1. 调整demo代码,扫描页面添加返回按钮callback(UnityView.h):
点击返回退出的回调

UnityView.mm 添加返回按钮UI, addBackBtn 方法在initWithFrame中调用:

- (void)addBackBtn{
    UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    backBtn.frame = CGRectMake(20, 20, 70, 40);
    [self addSubview:backBtn];
    [backBtn setTitle:@"< 返回" forState:UIControlStateNormal];
    [backBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [backBtn addTarget:self action:@selector(touchEvents) forControlEvents:UIControlEventTouchUpInside];
}

- (void)touchEvents{
    if (self.back) {
        self.back();
    }
}

------------------------------------->>

  • 4.在UnityAppController.h 中按如图修改: 修改方法
  • 5.在ViewController中添加开启AR代码:
- (IBAction)startAR:(id)sender {
    
    DTPUnityController *vc = [DTPUnityController instance];
    [vc initUnity];
}

以上就是全部过程了。

问题汇总

    1. 第一次运行demo 扫描后发现可以播放,但没有声音,音量也开到最大,以为是bug,找了好久,后面同事提示是否手机开了静音,煞笔了。。。。
    1. 当配置环境时,出现各种头文件引用报错,看是否引用了C C++代码 是的话看下文件是否.mm 结尾,不是的话要相应做修改 。另外,多数情况是Header Search Paths 路径有误,pch 文件合并,还有frameWork路径带来的报错,当然还有build setting 中的 C Language 设置。
    1. 有些报错还是无法解决,只能重新弄个工程集成了,xcode有时会抽风。
    1. 初始化在main 函数里面进行了,然后没找到返回按钮的退出api,只能暂停,然后调用unity 的移除模型api (若没有需要与unity 工程师沟通)。
    1. 最大的坑就是好不容易集成了,扫描无反应,扫描的图片都是需要在官网先注册的,然后有对应的.dat .xml 文件,扫描不了就是这两个文件路径有问题,具体路径设置代码在哪,还希望广大高手指出,非常感激。
    1. 项目多Target时,Target名不能为中文,否则会 EXC_BAD_ACCESS 闪退,原因尚且不知。

相关文章

  • 最新:iOS 集成Unity AR

    最近接到一个需求,要接入AR,给了个Vuforia官网地址,还有AR开发部们同事给的demo(需求以demo为主)...

  • iOS集成unity模块(Xcode 11.5--unity 2

    iOS集成unity模块(Xcode 11.5--unity 2019.3.3f1) 集成unity模块 打开项目...

  • 2022-03-30

    iOS集成Unity 近年来iOS和Unity发展都非常迅速,而iOS和Unity都有各自擅长的领域,iOS在传统...

  • 2017-11-09

    Easy Ar ios发布 不使用最新苹果系统导出unity工程 是万万不可的 如果开启了导出代码混淆 那么恭喜你...

  • Unity与iOS交互

    一、概要 本篇文章主要介绍Unity调用iOS方法,以及iOS调用Unity方法,回传信息。暂不涉及iOS集成第三...

  • iOS 中集成 Unity3D (附Demo)

    公司有个AR项目,对ios与u3d进行集成,需求如下,点击按钮进入Unity3D界面,并且能够返回,在网上找了一些...

  • iOS原生项目集成Unity3D项目说明

    本文主要讲述 iOS原生项目集成Unity3D项目的关键点说明 集成环境Unity 版本 2019.4.13f1c...

  • IOS手机项目,Unity2017,Vuforia6.5,坑

    前两天为了在IOS手机端测试AR应用,使用Vuforia6.5和unity2017.2. Unity信誓旦旦的说集...

  • Unity集成到iOS工程中资料

    1、Unity集成到iOS本地工程中(文字) http://qingqinghebiancao.github.io...

  • Unity项目集成到现有iOS项目

    Unity项目集成到现有iOS项目 1.将Unity项目文件复制到到iOS项目跟目录下 主要有5个文件,Class...

网友评论

  • 且听风吟SW:弱弱地问一下,AR 集成之后,项目如何瘦身?主要是 AR 资源包太大,八九百兆。上架之后,APP 大小是 140M。请指教!
    且听风吟SW:@No_longer_xie Android 的unity资源包是70多M,iOS 的是700多M,问unity,他也不知道!:joy:
    且听风吟SW:@No_longer_xie 谢谢,我试试!
    No_longer_xie:可以让unity同事帮忙减小下资源包大小, 或者开启bitCode试试(这个报错有时有,有时没有)

本文标题:最新:iOS 集成Unity AR

本文链接:https://www.haomeiwen.com/subject/shsdoftx.html