React Native集成Unity3D (一)

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 使用

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容