美文网首页
iOS集成UnityAR项目

iOS集成UnityAR项目

作者: 原味丿丿咖啡Vitas | 来源:发表于2019-02-22 15:06 被阅读0次

最近公司需要开发AR项目,在网上找来Unity项目研究了一下,用Unity生成iOS项目后需要导入到自己已有的项目中,步骤如下:

导入Unity项目文件

我们之前生成的Unity项目是这样的,我们需要导入的文件如下图标注


项目目录
  • 1.将Classes和Libraries文件以及Frameworks里面的Vuforia.framework 导入到我们项目,导入方式如下
Classes和Libraries文件以及Vuforia.framework 导入方式
  • 2 将Data文件导入,导入方式如下
Data文件导入方式
  • 3.将 Data / Raw 文件夹内的Vuforia文件夹按步骤二添加到如下位置
Vuforia
  • 4.将Classes目录下的main.mm 内容复制到自己项目中的 main.m 中,然后把main.m后缀改为.mm变成main.mm,删除导入Classes文件下的main.mm,修改后main.mm文件代码如下
       #import <UIKit/UIKit.h>
       #import "AppDelegate.h"
       #include "RegisterMonoModules.h"
       #include "RegisterFeatures.h"
       #include <csignal>

       static const int constsection = 0;

       void UnityInitTrampoline();

      // WARNING: this MUST be c decl (NSString ctor will be called after       +load, so we cant really change its value)
       const char* AppControllerClassName = "ViewController";

       int main(int argc, char * argv[]) {
          UnityInitStartupTime();
          @autoreleasepool {
    
              UnityInitTrampoline();
    
              UnityInitRuntime(argc, argv);
              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);
    
            //        return UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String: AppControllerClassName]);
           return UIApplicationMain(argc, argv, nil,   NSStringFromClass([AppDelegate class]));
    }
}
  • 5.在build Setting --> other Link Flags 做如下修改:
other Link Flags
-weak_framework
CoreMotion
-weak-lSystem
  • 6.在build Setting --> Header Search Paths 下做如下修改:
Header Search Paths
//具体根据文件目录而定
"$(SRCROOT)/BuddhaARDemo"  
"$(SRCROOT)/BuddhaARDemo/Classes"
"$(SRCROOT)/BuddhaARDemo/Classes/Native"
"$(SRCROOT)/BuddhaARDemo/Libraries"
"$(SRCROOT)/BuddhaARDemo/Libraries/libil2cpp/include"
  • 7.在build Setting --> Other C Flags 做如下修改:
Other C Flags
-DINIT_SCRIPTING_BACKEND=1
-fno-strict-overflow
-DRUNTIME_IL2CPP=1
  • 8.在build Setting --> Precompile Prefix Header 做如下修改(这里使用的是Unity项目中的pch文件,如BuddhaARDemo已有pch文件,需合并pch文件):
    Precompile Prefix Header
pch文件
  • 9.在build Setting 中做如下操作
0CD804D8ED94E500BF2F72EC8388B67E.jpg
GCC_THUMB_SUPPORT:NO 
GCC_USE_INDIRECT_FUNCTION_CALLS:NO 
UNITY_RUNTIME_VERSION:2018.2.9f1  <--这个值根据自己unity-demo来 
UNITY_SCRIPTING_BACKEND: il2cpp

效果如下

image.png
  • 10. build Setting --> bitcode关闭
  • 11. 添加Unity项目相关依赖库,如下两处需选择Optional,否则编译会报不必要的错误(具体根据你自己的Unity项目来)
相关依赖库
  • 12.在BuddhaARDemo的AppDelegate项目中写入以下代码

AppDelegate.h:

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

@interface AppDelegate : UIResponder <UIApplicationDelegate>

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

@end

AppDelegate.mm:

#import "AppDelegate.h"
#import "VTUnityController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    if (_unityController == nil) {
        _unityController = [[VTUnityController alloc]init];
    }
    return YES;
}


- (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
  • 13. 新建VTUnityController类,继承自UnityAppController

VTUnityController.h

#import "UnityAppController.h"

NS_ASSUME_NONNULL_BEGIN

@interface VTUnityController : UnityAppController
+ (instancetype)instance;

- (void)initUnity;

- (void)pauseUnity;

- (void)startUnity1;

- (BOOL)isPaused;
@end

NS_ASSUME_NONNULL_END

VTUnityController.m

#import "VTUnityController.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 VTUnityController()

@property (nonatomic, assign) BOOL isInitUnity;

@end

@implementation VTUnityController
+ (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
  • 14. 在需要的地方开启UnityAR
- (void)startAR {
  
    VTUnityController *vc = [VTUnityController instance];
    [vc initUnity];
}

效果如下

效果图

如遇到image not found,请参考我的另一篇文章

https://www.jianshu.com/p/cadd1dc95cf5

相关文章

网友评论

      本文标题:iOS集成UnityAR项目

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