美文网首页React Native实践
React Native集成Unity3D (一)

React Native集成Unity3D (一)

作者: light_of_king | 来源:发表于2016-11-27 00:54 被阅读2559次

    React Native与Unity3D的集成需要通过原生程序(iOS 、Android)

    这里先介绍iOS中的集成:

    1. 首先需要将Unity3D项目导出为iOS项目

    2. Auto Graphic API: 去掉钩,保留OpenGLES2,删除其他

    3. Target Device: 根据需要选择,我这里是默认的iPhone+iPad

    4. Target SDK:一般默认是Device SDK,如果是这个,那么导出之后只能在真机上看效果,我现在是这个,如果你希望能在模拟器上看效果,可以选择Simulator SDK,不过这样你就不能发布了。

    5. Scripting Backend:选择IL2CPP

    6. 导出完成后,就有两个选择了,一个是修改React Native项目生成的iOS程序,一个是修改Unity3D导出的iOS程序。

    <div style={"color : red"}>
    这里推荐修改Unity3D导出的iOS程序(修改React Native中的iOS程序,需要修改很多的Build Setting项,编译容易出错,非常麻烦)
    </div>

    修改React Native中的iOS程序

    1. 将Unity导出项目里面的Classes、Data、Libraries、MapFileParser、MapFileParser.sh拷贝到ios目录下面去
    
    2. 打开React Native中ios里面的xcode工程,导入Classes和Libraries,导入时选择Create groups(.h不需要导入)
    
    3. 导入Data时,需要选择Create folder reference
    
    4. 设置Xcode的参数:(按照Unity3D导出项目的参数设置)
    
    5. 修改文件
    

    详细请看这里

    修改Unity3D导出的iOS程序

    1. 引入 RCT 相关项目工程到 Libraries 目录下(可以使用cocoapods)

    2. Build Setting

    // 1. 在 Header search path 下添加路径,类型为 recursive (0.40以下)
    $(SRCROOT)/../node_modules/react-native/React   
    // react native 0.40 后,命名空间有变化,可能需要引入下面的路径
    $(BUILT_PRODUCTS_DIR)/include
    // 2. bitcode
    enable bitcode : NO
    // 3. other linker flag
    other linker flag  :   
    $(OTHER_LDFLAGS) -weak_framework CoreMotion -weak-lSystem -ObjC -lc++
    // 4. DEBUG宏支持,react native打包以此判断是否为离线包
    Preprocessor Macros > Debug 里设置 "DEBUG=1"
    
    1. Build Phases
     // 1. 添加 Run Script
     // 名称为 
     Bundle React Native code and images 
     // 内容填写 
     export NODE_BINARY=node
     ../node_modules/react-native/packager/react-native-xcode.sh
     // 2. Link Binary With Libraries
     添加react native组件库文件,根据需要添加其他库文件
    
    1. Capabilities
    // 根据需要打开功能
    HealthKit
    Push Notification
    
    1. 文件修改
    // 修改unity3d的UnityAppController.h中(注释为未修改的)
    inline UnityAppController* GetAppController(){
    //return (UnityAppController*)[[UIApplication sharedApplication].delegate;
      return (UnityAppController*)[[UIApplication sharedApplication]           valueForKeyPath:@"delegate.unityAppController"];
    }
    // 同时需要修改 main.mm
    // 引入文件
    #import "AppDelegate.h"
    // 修改
    const char* AppControllerClassName = "AppDelegate";
    // 修改AppDelegate文件,添加 unity3d 的初始化和相关处理
    // AppDelegate.h
    #import "UnityAppController.h"
    @property (nonatomic, strong) UnityAppController *unityAppController;
    // AppDelegate.m
      - (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions:  (NSDictionary *)launchOptions{
    ...
    // 添加 unity3d 代码
      BOOL returnBool;
      if (_unityAppController == nil) {
          _unityAppController = [[UnityAppController alloc]init];
      }
      returnBool = [_unityAppController application:application didFinishLaunchingWithOptions:launchOptions];
    ...
    }
    
    #pragma mark - same maeeage to unity
    -(void)applicationWillResignActive:(UIApplication *)application{
        [_unityAppController applicationWillResignActive:application];
    }
    -(void)applicationDidEnterBackground:(UIApplication *)application{
        [_unityAppController applicationDidEnterBackground:application];
    }
    -(void)applicationWillEnterForeground:(UIApplication *)application{
        [_unityAppController applicationWillEnterForeground:application];
    }
    -(void)applicationDidBecomeActive:(UIApplication *)application{
        [_unityAppController applicationDidBecomeActive:application];
    }
    -(void)applicationWillTerminate:(UIApplication *)application{
        [_unityAppController applicationWillTerminate:application];
    }
    
    
    1. 其他修改
    // debug log去除无用信息
      - Xcode menu -> Product -> Edit Scheme -> Arguments
      - Environment Variables -> Add -> Name:   
    "OS_ACTIVITY_MODE", Value:"disable"
    //
    - 调用 C++ 函数的 .m 文件 (使用GetAppController()方法)要改为 .mm
    
    1. info.plist 添加 View controller-based status bar appearance 为 NO;

    2. react native JS 支持
      创建 UIView类用来显示 unity3d界面,创建react native ViewManager 管理类,使其可以在 JSX 中调用

    // RCTUnityView.h
    #import <UIKit/UIKit.h>
    @interface RCTUnityView : UIView
    @property (nonatomic,strong)UIView *uView;
    @end
    
    // RCTUnityView.m
    #import "RCTUnityView.h"
    #import "UnityAppController.h"
    @interface RCTUnityView ()
    @property (nonatomic,strong) UIView * hide;
    @property (nonatomic,strong) NSTimer* timer;
    @end
    @implementation RCTUnityView
    static RCTUnityView * _instance;
    -(id)initWithFrame:(CGRect)frame{
      if (!_instance) {
          _instance = [super initWithFrame:frame];
          _instance.uView = (UIView*)GetAppController().unityView;
          _instance.uView.frame = frame;
          [_instance insertSubview:_instance.uView atIndex:0];
      }
      return _instance;
    }
    @end
    
    // RCTUnityViewManager.h
    #import "RCTViewManager.h"
    @interface RCTUnityViewManager : RCTViewManager
    @end
    
    // RCTUnityViewManager.m
    #import "RCTUnityViewManager.h"
    #import "RCTUIManager.h"
    #import "RCTUnityView.h"
    #import "UnityAppController.h"
    @implementation RCTUnityViewManager
    RCT_EXPORT_MODULE();
    @synthesize bridge = _bridge;
      - (UIView *)view{
        return [[RCTUnityView alloc] init] ;
      }
      - (dispatch_queue_t)methodQueue{
        return dispatch_get_main_queue();
      }
    @end
    
    // UnityViewNative.js
    import React, { Component, PropTypes } from 'react';
    import {requireNativeComponent,View,Dimensions} from 'react-native';
    const RCTUnityView = 
     requireNativeComponent('RCTUnityView',UnityViewNative);
    let  screenWidth = Dimensions.get('window').width;
    let  screenHeight = Dimensions.get('window').height;
    export default class UnityViewNative extends Component {
      render() {
        return <RCTUnityView 
                  style={{width:screenWidth ,height:screenHeight}}    
                  {...this.props}
                />
        }
    }
    
    1. 因为 Unity 3D导出项目与原 React Native 项目名称不同,react-native run-ios 会失败,这里需要修改项目的名称,与 React Native 项目相同,Rename 项目之后,发现运行那里仍然没有改变,还是不行,点击 Unity-iphone, 选择 Manager Schemes,删除 Unity-iphone, 再添加一个 name 为项目名称的即可!

    可以建立两个target , 方便debug 和 release 使用

    相关文章

      网友评论

        本文标题:React Native集成Unity3D (一)

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