⚠️ Warning: This is v1.0 documentation. Please use this link to read stable version 0.5.0 docs
npm install @wowmaking/react-native-unityMove your Unity project to
unityfolder at RN project rootAdd Newtonsoft Json Unity Package to Unity project
Add the following line at your
[rn_project_root]/unity/Packages/manifest.json:{..."com.wowmaking.react-native-unity": "file:../../node_modules/@wowmaking/react-native-unity/unity" }To receive commands from JavaScript create a new game object or use existing one. Commands receiver object should implement
IRNCommandsReceiverinterface:usingWowmaking.RNU;publicclassRNCommandsReceiver:MonoBehaviour,IRNCommandsReceiver{ ...}
Set your object as commands receiver to
RNBridgeonAwake:usingWowmaking.RNU;publicclassRNCommandsReceiver:MonoBehaviour,IRNCommandsReceiver{privatevoidAwake(){RNBridge.RegisterCommandsReceiver(this);}}
Implement
IRNCommandsReceiverinterface by addingHandleCommandmethod:usingWowmaking.RNU;publicclassRNCommandsReceiver:MonoBehaviour,IRNCommandsReceiver{privatevoidAwake(){RNBridge.RegisterCommandsReceiver(this);}publicvoidHandleCommand(RNCommandcommand){switch(command.name){command.Resolve(new{});// command.Reject(new{});}}}
⚠️ Important: CallResolveorRejectmethod of receivedRNCommandinstance to remove it from JavaScript thread
Run
pod installExport Unity app for iOS using Unity Editor menu options:
ReactNative → Export iOS (Device)- exports to[rn_project_root]/unity/builds/ios_deviceReactNative → Export iOS (Simulator)- exports to[rn_project_root]/unity/builds/ios_simulatorRename the folder with required sdk (
ios_deviceorios_simulator) toiosAdd
Unity-iPhone.xcodeprojto your RN project workspace in Xcode and add UnityFramework.framework (see step 3 and step 4) of Integrating Unity as a library into standard iOS app guideAdd the following lines to your project
main.mfile (located at same folder withAppDelegate)#import<UIKit/UIKit.h> #import<RNUnity/RNUnity.h>// ← Add this line #import"AppDelegate.h"intmain(int argc, char * argv[]){@autoreleasepool{[RNUnity setArgc:argc]; // ← Add this line [RNUnity setArgv:argv]; // ← Add this linereturnUIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]))} }
Add the following lines to
AppDelegate.mfile#import"AppDelegate.h" #import<React/RCTBridge.h> #import<React/RCTBundleURLProvider.h> #import<React/RCTRootView.h> #import<RNUnity/RNUnity.h>// ← Add this line@implementationAppDelegate - (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{[RNUnity launchWithOptions:launchOptions]; // ← Add this line before React root view creation RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:selflaunchOptions:launchOptions]; ... } // ↓ Add these lines - (void)applicationWillResignActive:(UIApplication *)application{[[[RNUnity ufw] appController] applicationWillResignActive: application]} - (void)applicationDidEnterBackground:(UIApplication *)application{[[[RNUnity ufw] appController] applicationDidEnterBackground: application]} - (void)applicationWillEnterForeground:(UIApplication *)application{[[[RNUnity ufw] appController] applicationWillEnterForeground: application]} - (void)applicationDidBecomeActive:(UIApplication *)application{[[[RNUnity ufw] appController] applicationDidBecomeActive: application]} - (void)applicationWillTerminate:(UIApplication *)application{[[[RNUnity ufw] appController] applicationWillTerminate: application]} // ↑ Add these lines@end
Make React root view background color transparent in
AppDelegate.mfile:rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0fgreen:1.0fblue:1.0falpha:0];
For RN v0.71+ this line is located in
[rn_project_root]/node_modules/react-native/Libraries/AppDelegate/RCTAppDelegate.mm, so use patch-package to modify it
Export Unity app for Android using Unity Editor menu option:
ReactNative → Export Android- exports to[rn_project_root]/unity/builds/androidConfigure your project to use only
armeabi-v7aandarm64-v8aarchitectures in[rn_project_root]/android/gradle.properties:reactNativeArchitectures=armeabi-v7a,arm64-v8a
For older RN versions add ndk section to
[rn_project_root]/android/app/build.gradle:defaultConfig{... ndk{abiFilters "armeabi-v7a", "arm64-v8a" } }
Append the following lines to
[rn_project_root]/android/settings.gradle:include ':unityLibrary' project(':unityLibrary').projectDir=newFile('..\\unity\\builds\\android\\unityLibrary')
Insert the following lines inside the dependencies block in
[rn_project_root]/android/app/build.gradle:implementation project(':unityLibrary') implementation files("${project(':unityLibrary').projectDir}/libs/unity-classes.jar")
Change parent activity in
MainActivity.javafromReactActivitytoUnityReactActivityimportcom.wowmaking.rnunity.UnityReactActivity; publicclassMainActivityextendsUnityReactActivity{... }
If you have any troubles while configuring Android project, please refer to Integrating Unity as a library into standard Android app guide
import{Unity,UnityResponderView}from'@wowmaking/react-native-unity';Unity.init();constApp=()=>{consthandlePress=()=>{Unity.execCommand('command_name',{/* any specific command data */});};return(<View>{/* UnityResponderView provides all touch events to Unity */}<UnityResponderView/><TouchableonPress={handlePress}>Press me!</Touchable></View>);};init- initializereact-native-unitylibUsage:
Unity.init();
execCommand- send command to UnityParams:
name(string) - Unity command namedata(Object, optional) - Unity command data
Return
PromiseUsage:
Unity.execCommand('command_name',{a: 1,b: 'b'});
addEventListener- add listener of Unity eventsParams: -
type(string) - type of Unity event -listener(function) - function, that's calling on Unity event receivingUsage:
Unity.addEventListener('event_type',e=>{console.warn(e);});
removeEventListener- remove Unity event listener Params: -type(string) - type of Unity event -listener(function) - specific listener to remove Usage:Unity.addEventListener('event_type',{ listener });
void HandleCommand(RNCommand command)- method, that calls from JavaScriptParams:
command(RNCommand) - command object, received from JavaScript
name(string) - name of received commanddata(object) - data of received command
Resolve- invoke on successful command executionParams:
data(object, optional) - object, that will receive JavaScript
Usage:
command.Resolve(new{text="test", });
Reject- invoke on unsuccessful command executionParams:
data(object, optional) - object, that will receive JavaScript
Usage:
command.Reject(new{text="test", });
RegisterCommandsReceiver- add commands reveiver to bridgeParams:
cReceiver(IRNCommandsReceiver) - game object, that implements IRNCommandsReceiver interface
Usage:
privatevoidAwake(){RNBridge.RegisterCommandsReceiver(this)}
SendEvent- send event to JavaScriptParams:
name(string) - event name, that receive JavaScriptdata(object) - data object, that receive JavaScript listeners
You can add some useful commands to package.json file of your RN project:
{"var":{"unity": "/Applications/Unity/Hub/Editor/2020.3.44f1/Unity.app/Contents/MacOS/Unity -batchmode -quit -logFile - -projectPath ./unity -buildTarget" }, "scripts":{"unity-export-android": "${npm_package_var_unity} Android -executeMethod Wowmaking.RNU.Editor.RNBuild.PerformAndroidBuild", "unity-export-device-ios": "${npm_package_var_unity} iOS -executeMethod Wowmaking.RNU.Editor.RNBuild.PerformIOSBuildForDevice", "unity-export-simulator-ios": "${npm_package_var_unity} iOS -executeMethod Wowmaking.RNU.Editor.RNBuild.PerformIOSBuildForSimulator", "unity-select-device-ios": "cd ./unity/Builds && rm -f ./ios && ln -s ./ios_device ./ios", "unity-select-simulator-ios": "cd ./unity/Builds && rm -f ./ios && ln -s ./ios_simulator ./ios" } }Replace 2020.3.44f1 with your Unity version
Due to changes in the Android native code in 2020.3.46+, 2021.3.19+, 2022.2.4+ versions of the Unity Editor, interaction with the Unity stops working with an error:
RNBridge: exception during try set receiver <java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "mUnityPlayer" in class "Lapp/example/MainActivity;" or its superclasses> We are working on a solution