⚠️ Warning: This is v1.0 documentation. Please use this link to read stable version 0.5.0 docs
npm install @wowmaking/react-native-unity
-
Move your Unity project to
unity
folder at RN project root -
Add 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
IRNCommandsReceiver
interface:using Wowmaking.RNU; public class RNCommandsReceiver : MonoBehaviour, IRNCommandsReceiver { ... }
-
Set your object as commands receiver to
RNBridge
onAwake
:using Wowmaking.RNU; public class RNCommandsReceiver : MonoBehaviour, IRNCommandsReceiver { private void Awake() { RNBridge.RegisterCommandsReceiver(this); } }
-
Implement
IRNCommandsReceiver
interface by addingHandleCommand
method:using Wowmaking.RNU; public class RNCommandsReceiver : MonoBehaviour, IRNCommandsReceiver { private void Awake() { RNBridge.RegisterCommandsReceiver(this); } public void HandleCommand(RNCommand command) { switch (command.name) { command.Resolve(new {}); // command.Reject(new {}); } } }
⚠️ Important: CallResolve
orReject
method of receivedRNCommand
instance to remove it from JavaScript thread
-
Run
pod install
-
Export Unity app for iOS using Unity Editor menu options:
ReactNative → Export iOS (Device)
- exports to[rn_project_root]/unity/builds/ios_device
ReactNative → Export iOS (Simulator)
- exports to[rn_project_root]/unity/builds/ios_simulator
-
Rename the folder with required sdk (
ios_device
orios_simulator
) toios
-
Add
Unity-iPhone.xcodeproj
to 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 guide -
Add the following lines to your project
main.m
file (located at same folder withAppDelegate
)#import <UIKit/UIKit.h> #import <RNUnity/RNUnity.h> // ← Add this line #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { [RNUnity setArgc:argc]; // ← Add this line [RNUnity setArgv:argv]; // ← Add this line return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
-
Add the following lines to
AppDelegate.m
file#import "AppDelegate.h" #import <React/RCTBridge.h> #import <React/RCTBundleURLProvider.h> #import <React/RCTRootView.h> #import <RNUnity/RNUnity.h> // ← Add this line @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [RNUnity launchWithOptions:launchOptions]; // ← Add this line before React root view creation RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions: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.m
file:rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha: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/android
-
Configure your project to use only
armeabi-v7a
andarm64-v8a
architectures 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=new File('..\\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.java
fromReactActivity
toUnityReactActivity
import com.wowmaking.rnunity.UnityReactActivity; public class MainActivity extends UnityReactActivity { ... }
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();
const App = () => {
const handlePress = () => {
Unity.execCommand('command_name', {
/* any specific command data */
});
};
return (
<View>
{/* UnityResponderView provides all touch events to Unity */}
<UnityResponderView />
<Touchable onPress={handlePress}>Press me!</Touchable>
</View>
);
};
-
init
- initializereact-native-unity
libUsage:
Unity.init();
-
execCommand
- send command to UnityParams:
name
(string
) - Unity command namedata
(Object
, optional) - Unity command data
Return
Promise
Usage:
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:
private void Awake() { 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