@brice-gros/react-native-unity-view v0.0.3
react-native-unity-view
Integrate unity3d within a React Native app. Add a react native component to show unity. Works on Android (TODO on iOS)
Notice
This is a fork of asmadsen/react-native-unity-view to make it work with node 16 LTS, React Native >= 0.63 and Unity 2020.3 LTS
This project may or may not be updated depending on the further use of it, feel free to fork it
Requirements
- Unity 2020.3+
- Nodejs 16.14+
- React Native 0.63
Prerequisites
Before anything, a React-Native app is needed, but beware, do not use Expo nor create-react-native-app which uses Expo or you'll have to eject it
nvm install 16.14.0
nvm use 16.14.0
npm install yarn
yarn install react-native
npx react-native init ReactUnityApp --template react-native-template-typescript
cd ReactUnityAppInstall
yarn add @brice-gros/react-native-unity-viewSince this project uses the exported data from Unity you will have more configuration steps than a normal React Native module.
Configure Native Build
For the react native project to recognize the unityLibrary folder which will contain the Unity exported project, some changes as to be done for each platform.
Android Build
To have gradle working properly, some modifications has to be done to the react native project:
- Add the following to the
android/build.gradle
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}So it looks like this
// [..]
allprojects {
repositories {
// [..]
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
}
}- Add these two lines to
android/settings.gradle
include ":unityLibrary"
project(":unityLibrary").projectDir = new File(rootProject.projectDir, './unityLibrary')- Add this line to
gradle.properties:
unityStreamingAssets=.unity3diOS build (TODO)
- Open your
ios/{PRODUCT_NAME}.xcworkspaceand add the exported project(ios/unityLibrary/Unity-Iphone.xcodeproj) to the workspace root

- Select the
Unity-iPhone/Datafolder and change the Target Membership to UnityFramework

- Add
UnityFramework.frameworkas a library to your Project

- Modify
main.m
#import "UnityUtils.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
InitArgs(argc, argv);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}Configuring Unity
To configure Unity to add the exported files to your app we use some build scripts. And the default configuration expects that you place your Unity Project in the following position relative to our app.
.
├── android
├── ios
├── unity
│ └── <Your Unity Project> // Example: Cube
├── node_modules
├── package.json
└── README.mdAdd Unity package
From the package manager menu (Window > Package Manager), select from the left corner Add package from git URL, and enter com.unity.nuget.newtonsoft-json and be sure to use version 3.0.1+
Add Unity scripts
Copy template scripts to your project:
cp -r node_modules/@brice-gros/react-native-unity-view/template/* ./unity/YourProject/This will add:
- Build.cs, controlling the build from the editor
- XCodePostBuild.cs, used for ios (TODO)
- UnityMessageManager.cs, a script managing the messages between React Native and Unity
- Rotate.cs, a MonoBehavior sample script rotating a game object controllable from react native, and sending back a message to react native
Player Settings
- Open your Unity Project
- Go to Player settings (File => Build Settings => Player Settings)
- Change
Product Nameto the name of your Xcode project. (ios/${XcodeProjectName}.xcodeproj)
◼️ Additional changes for Android Settings
Under Other Settings make sure:
Scripting Backendis set toIL2CPPApi Compatibility Levelis.NET Standard 2.0- under
Target Architectures,ARM64andARMv7are checked

◼️ Additional changes for iOS Settings (TODO)
Under Other Settings make sure Auto Graphics API is checked.

Export From Unity
To export, open the Build Settings window (File > Build Settings...).
💡 For a Development build with Script Debugging enabled, tick the corresponding boxes as usual.
⚠️ Don't use the Build or Export button, and note that using Switch platform is not required
👉 But export the Unity Project using ReactNative => Export Android (TODO or ReactNative => Export IOS).

Then the exported artifacts will be placed in a folder called unityLibrary inside either the android or ios folder.
🛠️ ANDROID KNOWN ISSUES:
On Android, the
local.propertiesfile from the Unity build folder will be added in your react native project asandroid/local.propertiesunless it already exists.An error message can require you to accept Android sdk manager licenses on the first Android build, this can be done using the following commandline:
# From the directory specified by `sdk.dir` in local.properties, run: ./tools/bin/sdkmanager.bat --licensesAlso, depending upon Gradle version, React Native project's
android/build.gradlecan contain andkVersionentry which is incompatible with thesdk.dirandndk.dirdefined bylocal.properties. In that case, either change it to match thendkVersionfrom the NDK atndk.dir, or comment both lines forsdk.dirandndk.dirinlocal.properties.
Use in React Native
UnityView Props
onMessage
Receive message from Unity
Make sure you have added UnityMessageManager
Example:
- Send message from Unity
UnityMessageManager.Instance.SendMessageToRN("click");- Receive message in React Native
onMessage(event) {
console.log('OnUnityMessage: ' + event.nativeEvent.message); // OnUnityMessage: click
}
render() {
return (
<View style={[styles.container]}>
<UnityView
style={style.unity}
onMessage={this.onMessage.bind(this)}
/>
</View>
);
}onUnityMessage
RecommendedReceive json message from unity.
onUnityMessage(handler) {
console.log(handler.name); // the message name
console.log(handler.data); // the message data
setTimeout(() => {
// You can also create a callback to Unity.
handler.send('I am callback!');
}, 2000);
}
render() {
return (
<View style={[styles.container]}>
<UnityView
style={style.unity}
onUnityMessage={this.onMessage.bind(this)}
/>
</View>
);
}UnityModule
import { UnityModule } from '@brice-gros/react-native-unity-view';isReady(): Promise<boolean>
Return whether is unity ready.
createUnity(): Promise<boolean>
Manual init the Unity. Usually Unity is auto created when the first view is added.
postMessage(gameObject: string, methodName: string, message: string)
Send message to unity.
gameObjectThe Name of GameObject. Also can be a path string.methodNameMethod name in GameObject instance.messageThe message will post.
Example:
- Add a message handle method in
MonoBehaviour.
public class Rotate : MonoBehaviour {
void handleMessage(string message) {
Debug.Log("onMessage:" + message);
}
}Add Unity component to a GameObject.
Send message use javascript.
onToggleRotate() {
if (this.unity) {
// gameobject param also can be 'Cube'.
UnityModule.postMessage('GameObject/Cube', 'toggleRotate', 'message');
}
}
render() {
return (
<View style={[styles.container]}>
<UnityView
ref={(ref) => this.unity = ref}
style={style.unity}
/>
<Button label="Toggle Rotate" onPress={this.onToggleRotate.bind(this)} />
</View>
);
}postMessageToUnityManager(message: string | UnityViewMessage)
Send message to UnityMessageManager.
Please copy UnityMessageManager.cs to your unity project and rebuild first.
Same to postMessage('UnityMessageManager', 'onMessage', message)
This is recommended to use.
messageThe message will post.
Example:
- Add a message handle method in C#.
void Awake()
{
UnityMessageManager.Instance.OnMessage += toggleRotate;
}
void onDestroy()
{
UnityMessageManager.Instance.OnMessage -= toggleRotate;
}
void toggleRotate(string message)
{
Debug.Log("onMessage:" + message);
canRotate = !canRotate;
}- Send message use javascript.
onToggleRotate() {
UnityModule.postMessageToUnityManager('message');
}
render() {
return (
<View style={[styles.container]}>
<UnityView
ref={(ref) => this.unity = ref}
style={style.unity}
/>
<Button label="Toggle Rotate" onPress={this.onToggleRotate.bind(this)} />
</View>
);
}addMessageListener(listener: (message: string | MessageHandler) => void): number
Receive string and json message from unity.
addStringMessageListener(listener: (message: string) => void): number
Only receive string message from unity.
addUnityMessageListener(listener: (handler: MessageHandler) => void): number
Only receive json message from unity.
pause()
Pause the unity player.
resume()
Resume the unity player.
Example Code
import React from 'react';
import { StyleSheet, View } from 'react-native';
import UnityView from '@brice-gros/react-native-unity-view';
export default class App extends React.Component {
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<UnityView style={{ flex: 1 }}/>
</View>
</View>
);
}
}See github repository for a complete example