美文网首页
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