iOS+Unity iOS项目整合 Unity AR+3D(Un

作者: 与之书 | 来源:发表于2017-08-24 11:30 被阅读382次

    swift整合版详见-->swift4.0+xCode9.1+Unity5.4

    1、项目准备

    工程截图.png Unity工程.png

    1.1 首先要有一个Unity工程和IOS工程
    1.2 Unity导出时可选 模拟器模式真机模式,导出后只能在对应的设备运行
    1.3 确保导出的unity可以直接运行
    1.4 建议在将Unity和IOS放在同一目录下

    2.导入

    拖动.png group.png

    2.1 在xcode中创建一个group,例如“Unity”,主要便于分类
    2.2 拖入操作有三个选项,是否复制、创建组或者关联、添加到目标
    建议都不要复制(复制会将内容添加到IOS项目中,后续替换起来麻烦)
    而参见1.4操作,更新时,每次替换Unity目录即可
    2.3 Classes和Libraries 选择groups
    Data文件选择reference
    网上很多教程要删除Unity下的一些.h文件,不删也没关系(因为头文件太多,每次删都要好久,只要你不点开,这个只会对你的xcodeproj文件大小有一点点很小的影响)
    2.4 特别的,如果使用VR功能,Data文件夹下Raw文件夹中的QCAR和Vuforia要再拖一次放在根目录(原因不明),如下图

    vr.png

    3 添加framework

    framework.png

    3.1 就是这么多。。。大家也可以参照导出的Unity工程下的Framework进行添加

    4 配置

    打开Building Setting

     Build Optons
          Enable Bitcode    NO
     Linking    
         Other Linker Flags
              -weak_framework
              CoreMotion
              -weak-lSystem
              -Wl,-undefined,dynamic_lookup **可以不加,如果报metal相关的错误可以加一下**
    Other C Flags
          -DINIT_SCRIPTING_BACKEND=1
    C Language Dialect
            选择 C99 
    C++ Language Dialect 
            选择 C++ 11
    

    4.1 Search Path
    添加头文件路径和库文件路径


    头文件.png

    这里不用手打,可以直接拖进去添加
    4.2 库路径


    库文件.png
    如果导出的Unity下有 plugin/ios 也添加进去
    4.3 如果报头文件找不到之类的错误,看这里是否把包含头文件的路径都添加进去了
    4.4 如果报link错误,看库路径是否都添加完整

    4.5 其他配置


    其他配置1.png
    其他配置2.png

    **关于配置部分比较麻烦,有两个方式参考:
    1、参照导出的Unity项目的Building Setting
    2、参照nerd (大神?)的视频教程, 原地址https://vimeo.com/145572230 (不太稳定)
    **

    5. 文件修改

    5.1 修改pch
    创建一个新的pch文件,找到原有的pch文件,复制到自定义的pch文件,并添加一行,如下图


    原有的pch.png
    自定义的pch.png

    5.2 Building Setting中修改


    添加pch路径.png

    5.3 修改main文件
    找到Unity的main.mm文件,直接复制到ios的main.m文件中(原有内容注释或者删除),并将文件名改为main.mm
    找到

    const char* AppControllerClassName = "UnityAppController";
    

    替换为

    const char* AppControllerClassName = "AppDelegate";
    

    5.4 打开Build Phases 搜索main.mm会有两个文件,删除Unity下的main.mm(否则会编译冲突)
    (如果报错,duplicate xxx 多半是因为这个文件重复)

    6 工程文件修改

    6.1 APPDelegate.h

    #import <UIKit/UIKit.h>
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    @property (strong, nonatomic) UIWindow *window;
    @property (strong,nonatomic) UnityAppController *unityAppController;
    //@property (nonatomic,strong) UINavigationController *navVC;
    @property (nonatomic, strong) UIWindow *unityWindow;
    - (void)hideUnityWindow;
    - (void)showUnityWindow;
    @end
    

    6.2 APPDelegate.m

    #import "AppDelegate.h"
    
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    // Unity相关方法
    - (UIWindow *)unityWindow{
        return UnityGetMainWindow();
    }
    
    - (void)showUnityWindow{
        UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [backButton setImage:[UIImage imageNamed:@"close.png"] forState:UIControlStateNormal];
        [backButton setAlpha:0.4];
        [backButton setFrame:CGRectMake(self.unityWindow.frame.size.width-60, 10, 50, 50)];
        [backButton addTarget:self action:@selector(hideUnityWindow) forControlEvents:UIControlEventTouchUpInside];
    
        [self.unityWindow addSubview:backButton];
        [self.unityWindow makeKeyAndVisible];
    }
    
    - (void)hideUnityWindow{
        [self.window makeKeyAndVisible];
    }
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        self.unityAppController=[[UnityAppController alloc] init];
        [self.unityAppController application:application didFinishLaunchingWithOptions:launchOptions];
        
        return YES;
    }
    
    
    - (void)applicationWillResignActive:(UIApplication *)application {
       
        [self.unityAppController applicationWillResignActive:application];
    }
    
    
    - (void)applicationDidEnterBackground:(UIApplication *)application {
        [self.unityAppController applicationDidEnterBackground:application];
    }
    
    
    - (void)applicationWillEnterForeground:(UIApplication *)application {
        [self.unityAppController applicationWillEnterForeground:application];
    }
    
    
    - (void)applicationDidBecomeActive:(UIApplication *)application {
        [self.unityAppController applicationDidBecomeActive:application];
    }
    
    
    - (void)applicationWillTerminate:(UIApplication *)application {
        [self.unityAppController applicationWillTerminate:application];
    }
    
    
    @end
    

    6.3 UnityAppController.h

    两个地方
    @class UnityViewControllerBase;

    #import "AppDelegate.h"
    inline UnityAppController* GetAppController(){
       AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
       return delegate.unityAppController;
    }
    
    #pragma once
    
    #import <QuartzCore/CADisplayLink.h>
    
    #include "PluginBase/RenderPluginDelegate.h"
    
    @class UnityView;
    @class UnityViewControllerBase;
    @class DisplayConnection;
    
    @interface UnityAppController : NSObject<UIApplicationDelegate>
    {
        UnityView*          _unityView;
        CADisplayLink*      _displayLink;
    
        UIWindow*           _window;
        UIView*             _rootView;
        UIViewController*   _rootController;
        UIView*             _snapshotView;
    
        DisplayConnection*  _mainDisplay;
    
        // we will cache view controllers for fixed orientation
        // auto-rotation view contoller goes to index=0
        UnityViewControllerBase* _viewControllerForOrientation[5];
    #if !UNITY_TVOS
        UIInterfaceOrientation  _curOrientation;
    #endif
    
        id<RenderPluginDelegate>    _renderDelegate;
    }
    
    // override it to add your render plugin delegate
    - (void)shouldAttachRenderDelegate;
    
    // this one is called at the very end of didFinishLaunchingWithOptions:
    // after views have been created but before initing engine itself
    // override it to register plugins, tweak UI etc
    - (void)preStartUnity;
    
    // this one is called at first applicationDidBecomeActive
    // NB: it will be started with delay 0, so it will run on next run loop iteration
    // this is done to make sure that activity indicator animation starts before blocking loading
    - (void)startUnity:(UIApplication*)application;
    
    // this is a part of UIApplicationDelegate protocol starting with ios5
    // setter will be generated empty
    @property (retain, nonatomic) UIWindow* window;
    
    @property (readonly, copy, nonatomic) UnityView*            unityView;
    @property (readonly, copy, nonatomic) CADisplayLink*        unityDisplayLink;
    
    @property (readonly, copy, nonatomic) UIView*               rootView;
    @property (readonly, copy, nonatomic) UIViewController*     rootViewController;
    @property (readonly, copy, nonatomic) DisplayConnection*    mainDisplay;
    
    #if !UNITY_TVOS
    @property (readonly, nonatomic) UIInterfaceOrientation      interfaceOrientation;
    #endif
    
    @property (nonatomic, retain) id                            renderDelegate;
    @property (nonatomic, copy)                                 void(^quitHandler)();
    
    @end
    
    // Put this into mm file with your subclass implementation
    // pass subclass name to define
    
    #define IMPL_APP_CONTROLLER_SUBCLASS(ClassName) \
    @interface ClassName(OverrideAppDelegate)       \
    {                                               \
    }                                               \
    +(void)load;                                    \
    @end                                            \
    @implementation ClassName(OverrideAppDelegate)  \
    +(void)load                                     \
    {                                               \
        extern const char* AppControllerClassName;  \
        AppControllerClassName = #ClassName;        \
    }                                               \
    @end
    
    #import "AppDelegate.h"
    
    inline UnityAppController*  GetAppController()
    {
        AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
        return delegate.unityAppController;
    }
    
    #define APP_CONTROLLER_RENDER_PLUGIN_METHOD(method)                         \
    do {                                                                        \
        id<RenderPluginDelegate> delegate = GetAppController().renderDelegate;  \
        if([delegate respondsToSelector:@selector(method)])                     \
            [delegate method];                                                  \
    } while(0)
    
    #define APP_CONTROLLER_RENDER_PLUGIN_METHOD_ARG(method, arg)                \
    do {                                                                        \
        id<RenderPluginDelegate> delegate = GetAppController().renderDelegate;  \
        if([delegate respondsToSelector:@selector(method:)])                    \
            [delegate method:arg];                                              \
    } while(0)
    
    
    
    // these are simple wrappers about ios api, added for convenience
    void AppController_SendNotification(NSString* name);
    void AppController_SendNotificationWithArg(NSString* name, id arg);
    
    void AppController_SendUnityViewControllerNotification(NSString* name);
    
    

    主要参照了the-nerd的文章
    https://the-nerd.be/2015/11/13/integrate-unity-5-in-a-native-ios-app-with-xcode-7/
    视频参见:https://vimeo.com/145572230 (经常无法解析)
    重新在b站传了一份,参见:https://www.bilibili.com/video/av13740194/

    以上,是使用两个window交互显示的方式,可以用最基本的Unitydemo测试一下,OK在导入完整的Unity项目。
    至于如何在某个页面的某个View上显示Unity,下一篇再说

    相关文章

      网友评论

      • swj沈:简主你好ld: warning: arm64 function not 4-byte aligned: ltmp0 from /Users/~~/Desktop/FinalDemo/Libraries/libiPhone-lib.a(unwind_test_arm64.o)
        ld: warning: arm64 function not 4-byte aligned: _unwind_tester from /Users/~~/Desktop/FinalDemo/Libraries/libiPhone-lib.a(unwind_test_arm64.o)
        Undefined symbols for architecture arm64:
        "_MTAudioProcessingTapGetSourceAudio", referenced from:
        AVFoundationVideoPlayback::PlayerPriv::ProcessAudioTap(opaqueMTAudioProcessingTap const*, long, unsigned int, AudioBufferList*, long*, unsigned int*) in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        "_MTAudioProcessingTapCreate", referenced from:
        -[AVFoundationMediaLoader ConfigureAudioOutput] in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        "_MTAudioProcessingTapGetStorage", referenced from:
        -[AVFoundationMediaLoader ConfigureAudioOutput] in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        AVFoundationVideoPlayback::PlayerPriv::PrepareAudioTap(opaqueMTAudioProcessingTap const*, long, AudioStreamBasicDescription const*) in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        AVFoundationVideoPlayback::PlayerPriv::ProcessAudioTap(opaqueMTAudioProcessingTap const*, long, unsigned int, AudioBufferList*, long*, unsigned int*) in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        AVFoundationVideoPlayback::PlayerPriv::FinalizeAudioTap(opaqueMTAudioProcessingTap const*) in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        -[AVFoundationMediaLoader StopOutput] in libiPhone-lib.a(AVFoundationVideoPlayback.o)
        ld: symbol(s) not found for architecture arm64
        clang: error: linker command failed with exit code 1 (use -v to see invocation) 这个怎么破
        与之书:@swj沈 library那些再看下 这个原因有点多…实在不行 把unity自动生成的再对照下
        swj沈:@与之书 frameWork对照了好几次了,包括哪些是optional的,很是奔溃啊
        与之书:@swj沈 感觉像是少了依赖库 Framework那些再对一下看?

      本文标题:iOS+Unity iOS项目整合 Unity AR+3D(Un

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