AR/VR/MR

最新:iOS 集成Unity AR

2018-09-26  本文已影响173人  No_longer_xie

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

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

目录

配置依赖
Demo封装
问题汇总

配置依赖

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


demo目录

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


Vuforia

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

#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]));
    }
}

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

 -weak_framework CoreMotion -weak-lSystem
other Link Flags

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

"$(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

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

-DINIT_SCRIPTING_BACKEND=1 -fno-strict-overflow -DRUNTIME_IL2CPP=1
如图所示: Other C Flags

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

注:若ARTest项目有pch 文件,需合并pch 文件,将Classes内的prefix.pch 内容全部拷贝到本项目中的pch 中,否则编译会报错,如图: PCH文件合并

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

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

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
#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
点击返回退出的回调

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

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

- (IBAction)startAR:(id)sender {
    
    DTPUnityController *vc = [DTPUnityController instance];
    [vc initUnity];
}

以上就是全部过程了。

问题汇总

上一篇 下一篇

猜你喜欢

热点阅读