美文网首页
iOS集成unity模块(Xcode 11.5--unity 2

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

作者: 7436101009b8 | 来源:发表于2020-06-08 11:13 被阅读0次

    iOS集成unity模块(Xcode 11.5--unity 2019.3.3f1)

    集成unity模块

    1. 打开项目工程(A工程)和unity导出工程(B工程)文件夹,让A工程页面处于有.xcodeproj目录下,找到B工程中的Classes,Libraries和Data文件夹,先直接复制粘贴到工程当前目录下,然后通过拖拽的方式,将Classes和Libraries添加到项目中,同时勾选Create groups;data也拖拽到项目中并勾选Create folder references。注意在Xcode中各文件夹处于同一层级。
    1. 找到导入的B工程的.pch文件,全选复制到A工程原有.pch中,并将A工程原有的#import ... 都放到#ifdef __OBJC__#endif之间。然后添加#import "UnityAppController.h",并删除导入的B工程的.pch文件。
    1. 接下来就是一些Build Setting的配置了。
      • Enable Bitcode:NO;

      • Other Linker Flags添加(注意:一定要按顺序)-weak_framework CoreMotion -weak-lSystem -licucore

      • 对Classes和Libraries的路径进行配置;

        在Header Search Paths中添加:
        $(SRCROOT)/Classes
        $(SRCROOT)/Classes/Native
        $(SRCROOT)/Libraries/libil2cpp/include

        在Library Search Paths中添加:
        $(PROJECT_DIR)/Libraries(如有,则不需要重复添加)
        $(PROJECT_DIR)/Libraries/Plugins/iOS

      • Other C Flags添加 -DINIT_SCRIPTING_BACKEND=1-DRUNTIME_IL2CPP=1

      • 设置Enable C++ Runtime Types:NO

      • 设置Overriding Deprecated Objective-C Methods:Yes

      • 设置Unintentional Root Class:Yes

      • 添加用户设置Add User-Defined Setting共4项:

      GCC_THUMB_SUPPORT : NO
      GCC_USE_INDIRECT_FUNCTION_CALLS : NO
      UNITY_RUNTIME_VERSION : 2019.3.3f1(看B工程中Unity实际版本号)
      UNITY_SCRIPTING_BACKEND : il2cpp
    
    1. 然后是Build Phases配置Link Binary With Libraries,根据B工程中Build Phases里引入的库照搬照抄即可,需要注意的是status也要和B工程中的相同,如果.a文件没有就去刚刚导入到A工程中的Library文件夹里找。

    2. 新建UnityFramework.framework,并设置.framework配置。通过TARGETS添加新的framework,并按照B工程中UnityFramework.framework的配置设置新建framework的Build Settings和Build Phases。还要记得把B工程中UnityFramework.h的内容复制到新的framework里。


    修改原iOS项目内容

    1. 将Classes文件夹中main.mm代码全都复制到A工程原有main.m下方,设置AppControllerClassName = "AppDelegate",并将.m改为.mm,再删除Classes中的main.mm。

    main.mm中还需要注意的一点,将刚才新建的framework也要引入进来,并且把运行条件添加上。在B工程中也有,可以直接复制。

    #include <UnityFramework/UnityFramework.h>
    UnityFramework* UnityFrameworkLoad()
    {
        NSString* bundlePath = nil;
        bundlePath = [[NSBundle mainBundle] bundlePath];
        bundlePath = [bundlePath stringByAppendingString: @"/Frameworks/UnityFramework.framework"];
        NSBundle* bundle = [NSBundle bundleWithPath: bundlePath];
        if ([bundle isLoaded] == false) [bundle load];
        UnityFramework* ufw = [bundle.principalClass getInstance];
        if (![ufw appController])
        {
            // unity is not initialized
            [ufw setExecuteHeader: &_mh_execute_header];
        }
        return ufw;
    }
    
    1. 修改UnityAppController.mm文件,将GetAppController()方法的实现改为AppDelegate中的Controller。

      UnityAppController* GetAppController()
      {
          //删除原有返回值
      //    return _UnityAppController;
          return (UnityAppController *)[[UIApplication sharedApplication] valueForKeyPath:@"delegate.unityController"];
      }
      
    1. 接下来修改AppDelegate.h和AppDelegate.m文件,等等,在修改AppDelegate之前最好再加一步,就是新建一个Controller,继承UnityAppController,避免修改UnityAppController文件中的内容,并且要把.m改为.mm。

      SSSUnityController.h如下

      #import <UnityFramework/UnityFramework.h>
      
      @interface SSSUnityController : UnityAppController
      
      + (instancetype)instance;
      - (void)initUnity;
      - (void)pauseUnity;
      - (void)startUnity1;
      - (BOOL)isPaused;
      
      @end
      

      SSSUnityController.mm如下

      #import "SSSUnityController.h"
      
      #import "AppDelegate.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>
      
      
      @interface SSSUnityController()
      
      @property (nonatomic, assign) BOOL isInitUnity;
      
      @end
      
      @implementation SSSUnityController
      
      + (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];
      }
      
      extern "C" {
          void ReturnToIOS() {
              
              AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
              [delegate hideUnityWindow];
          }
      }
      
      - (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. 现在可以对AppDelegate进行修改了,引入刚才的新建子类SSSUnityController,添加用来展示unity内容的window,添加展示和隐藏window的方法。

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

    AppDelegate.m中要在- (BOOL)application:didFinishLaunchingWithOptions:方法中添加初始化SSSUnityController的代码,_unityController = [[SSSUnityController alloc]init];,同时实现.h中的方法。

    - (UIWindow *)unityWindow {
        if (!_unityWindow) {
            if (!UnityGetMainWindow()) {
                _unityWindow = [[UIWindow alloc]initWithFrame:UIScreen.mainScreen.bounds];
                _unityWindow.backgroundColor = [UIColor redColor];
            }else{
                _unityWindow = UnityGetMainWindow();
            }
        }
        return _unityWindow;
    }
    
    - (void)showUnityWindow {
        [self.unityWindow makeKeyAndVisible];
    }
    
    - (void)hideUnityWindow {
        [self.window makeKeyAndVisible];
        [self.unityController pauseUnity];
    }
    
    1. 在A工程需要跳转到unity的地方设置入口即可。比如我在ViewController中创建了按钮,点击按钮事件就为:

      //点击按钮
      - (void)btnClicked {
          
          SSSUnityController *vc = [SSSUnityController instance];
          [vc initUnity];
      }
      
    1. 设置A工程的Edit Scheme的Build Configuration为Release,因为unity内容无法在debug环境下运行。当然我们可以通过项目配置设置debug和release环境进行区分,然后将Classes文件夹下的DynamicLibEngineAPI-functions.h中的内容,设置到release中。
    1. 此时基本配置都已经完成了,但仍然运行不了,因为在导入进来的Libraries文件夹中,只有RegisterMonoModules.cpp,缺少RegisterMonoModules.h文件,需要我们手动添加一个.h文件。
    1. 这样再运行就不出出现报错了!

    可能出现的问题

    我在集成的过程中基本上没有出现什么问题,unity设置上看到一个,也不知道是否有用,这里也都一并写出吧。

    1. 取消Auto Graphics API的勾选并移除Metal选择OpenGLES2(补充:取消勾选,选择Metal也能成功,根据相关报错信息自行修改)

    2. 取消Strip Engine Code的勾选

    替换unity内容

    如果要替换untiy的内容,只需把Data文件夹和Classes中的Native文件夹删除替换即可,导入方式还与原来相同,unity的内容就会替换了。

    祝大家都可以成功集成unity模块~!

    相关文章

      网友评论

          本文标题:iOS集成unity模块(Xcode 11.5--unity 2

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