React Native与Unity3D的集成需要通过原生程序(iOS 、Android)
这里先介绍iOS中的集成:
首先需要将Unity3D项目导出为iOS项目
Auto Graphic API: 去掉钩,保留OpenGLES2,删除其他
Target Device: 根据需要选择,我这里是默认的iPhone+iPad
Target SDK:一般默认是Device SDK,如果是这个,那么导出之后只能在真机上看效果,我现在是这个,如果你希望能在模拟器上看效果,可以选择Simulator SDK,不过这样你就不能发布了。
Scripting Backend:选择IL2CPP
导出完成后,就有两个选择了,一个是修改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程序
引入 RCT 相关项目工程到 Libraries 目录下(可以使用cocoapods)
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"
- 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组件库文件,根据需要添加其他库文件
- Capabilities
// 根据需要打开功能
HealthKit
Push Notification
- 文件修改
// 修改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];
}
- 其他修改
// debug log去除无用信息
- Xcode menu -> Product -> Edit Scheme -> Arguments
- Environment Variables -> Add -> Name:
"OS_ACTIVITY_MODE", Value:"disable"
//
- 调用 C++ 函数的 .m 文件 (使用GetAppController()方法)要改为 .mm
info.plist 添加
View controller-based status bar appearance
为 NO;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}
/>
}
}
- 因为 Unity 3D导出项目与原 React Native 项目名称不同,react-native run-ios 会失败,这里需要修改项目的名称,与 React Native 项目相同,Rename 项目之后,发现运行那里仍然没有改变,还是不行,点击 Unity-iphone, 选择 Manager Schemes,删除 Unity-iphone, 再添加一个 name 为项目名称的即可!
可以建立两个target , 方便debug 和 release 使用