This project is basically an exploratory investigation to see if it is possible to integrate React to Unity Android App.
Last Update: 07/15/2018
The idea is to build React project and integrate into Android module (i.e. aar or jar).
Then Unity will invoke React component via the Android module we just created.
To invoke React component from within Unity app, Unity project will need to be exported as a Gradle project due to the issue of React does not support 64-bit and if your existing Unity project is large and has integrated a bunch of 3rd party library, you may have exceeded DEX counts limit by just adding React-Native library. These can only be resolved via a custom build.gradle.
- Unity 5.6.5p1
- Node installed via Homebrew
- React-Native version 0.56.0
- Android Studio
- Android SDK from version 16 to the latest one
- Android Build Tools at least version 25 (Recommended 27)
ReactAndroid // React Project
.../ReactProject
.../.../native_android // Android App and Module projects for React
.../.../android/EXPORT_PROJECT_NAME // Exported Unity to Android Project
UnityClient // Unity Project
.../Assets/Plugins/Android/ // Android Plugins and Unity's custom gradle template
Follow https://facebook.github.io/react-native/docs/integration-with-existing-apps for step 1 to step 3.
If using this React-Native from this repo (ReactAndroid/ReactProject), run the following command to reconstruct android folder:
react-native upgrade
This is basically what Android Application/module will use for rendering your React-Native project. Think of it as your React executable file.
Run this script:
sh build.sh
It is essentially equivalent to running the following command to build index.android.bundle with additional steps of copy the bundle file your project folder.
react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
Everytime you've made a change to your React-Native project. You will need to run this command in order to have your changes reflected.
If you're unable to use or import com.facebook.react.ReactRootView and com.facebook.react.ReactInstanceManager,
it is bacause Maven is unable to find React-Native package version we need (see 3.2).
Please check the followings:
allprojects {
repositories {
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
...
}
...
}
dependencies {
...
compile "com.facebook.react:react-native:+" // From node_modules
}
** DO THIS INSTEAD, Specify react-native version to use. **
dependencies {
...
compile "com.facebook.react:react-native:0.56.0" // From node_modules
}
If you use gradle command,
./gradlew clean build
Once step#3 works and there is no issue,
- Create a new Android Module Project.
- Modify
build.gradleto includeReact-nativeas dependencies, should be similar to step#1 to step#3. - Move all React related activity to this module.
- Create a static method to launch
Reactactivity. - Add this module as a dependency for your Android Project in step#3.
- Test your Android Project from step#3 to see if it still works.
Once you reach this, Congratulations!
- Create a button in Unity, which is basically going to call the static method from step#4 via JavaObject and JavaClassObject i.e.
AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass reactNativeActivity = new AndroidJavaClass("YOUR_PACKAGE_NAME.YOUR_MODULE_JAVA_CLASS");
reactNativeActivity.CallStatic("YOUR_STATIC_METHOD", currentActivity);
This will get copied over to Gradle project once exported.
https://docs.unity3d.com/Manual/android-gradle-overview.html
We need to do this because of the followings:
Reactdoes NOT support 64 bit.- Avoid exceed the limit of Android dex counts.
- Unity uses old
Gradleversion, which lacks some of the functionality we may need (i.e. ability to exclude 64 bit).
- Under
File->Build Settings - Check
Export Project - Change
Build SystemtoGradle (New) - Click Export
OR
(preferably)
[MenuItem("Build/Android Project %g", false, 1)]
public static void BuildAndroid()
{
...
// Export as Gradle/Android project
EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
BuildOptions options = BuildOptions.AcceptExternalModificationsToPlayer;
string status = BuildPipeline.BuildPlayer (
GetEnabledScenes(),
path, // This should point to 'YOUR_REACT_NATIVE_PROJECT/android'.
BuildTarget.Android,
options
);
return status;
}
This will create your Unity's Android Gradle project.
NOTE: It should reside in your React-Native project's android folder due to recommendation from Facebook:
To ensure a smooth experience, create a new folder for your integrated React Native project, then copy your existing Android project to an /android subfolder.
NOTE: Please make sure to be able to build and launch your APK successfully (minus React part). Otherwise, we would have a non-functioning Gradle project.
but ** DO NOT ** use the default gradle setting suggested by Android Studio.
This is located in ReactAndroid/ReactProject/android/UnityReactTest. It was exported from Unity.
This is basically Unity's Android project building with Gradle.
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "x86"
}
dependencies {
...
compile 'com.facebook.react:react-native:0.56.0'
}
dependencies {
...
compile 'com.android.support:appcompat-v7:27.1.1'
compile 'com.android.support.constraint:constraint-layout:1.1.2'
}
project.ext.react = [
entryFile: "index.js"
]
apply from: "../../node_modules/react-native/react.gradle"
9.1.6) Apply jcenter() under respositories of allprojects and buildscript sections to ensure React-Native package has all required dependencies.
buildscript {
repositories {
maven { url 'https://maven.google.com' }
jcenter()
}
allprojects {
repositories {
...
jcenter()
}
}
This ensures React-Native package has all the required dependencies.
- Your android module
aarfromReactAndroid/ReactProject/native_android/YOUR_MODULE_NAME/builds/outputs/YOUR_MODULE.ARR react-native-0.56.0.aarfrom yourReactAndroid/ReactProjet/node_modules/react-native/android/com/facebook/react/react-native/0.56.0/project.
NOTE: node_modules folder was generated after you create React-Native project via react-native command, run npm install, or run react-native run-android.
9.3) Copy index.android.bundle to ReactAndroid/ReactProject/android/UnityReactTest/src/main/assets/ folder.
If you've set things up correctly, you'd be able to trigger React project from within Unity.
- No support for 64 bit. Must exclude 64 bit by modify
build.gradle. - Dex counts will blow up if your Unity project contains a lot of 3rd party library. React-Native library will add at least 5000+ more to dex count.
- Don't use default Gradle version when import Unity Android project to Android Studio. Otherwise, you may get into dependencies hell.
- If react-native library is missing dependencies, make sure to add
jcenter()tobuild.gradle.
Nate Kemavaha
Thank you for all contributors to these references. Without them, we wouldn't have this project working.
- Could not find dependency: https://stackoverflow.com/questions/41570435/gradle-error-could-not-find-com-android-tools-buildgradle2-2-3
- Troubleshooting Android Guide: http://shobhitsamaria.com/troubleshooting-unity-build-android-platform/
- Unable to load
index.android.bundle: https://stackoverflow.com/questions/44446523/unable-to-load-script-from-assets-index-android-bundle-on-windows - Tip for how to change
index.android.jsentry: facebook/react-native#3442 - Unity-React Project from
marijnfor a different approach toUnityandReact: https://github.com/marijnz/unity-react - How to include external
aarusing Gradle: https://stackoverflow.com/questions/16682847/how-to-manually-include-external-aar-package-using-new-gradle-android-build-syst - Unity3D and React-Native Troubleshooting List: https://answers.unity.com/questions/1083233/unity3d-react-native.html
- Export and running Unity3D to Android Studio: https://stackoverflow.com/questions/38980792/exporting-and-running-unity3d-project-to-android-studio
- Proguard and how to check dependencies: https://stackoverflow.com/questions/43496103/prograurd-duplicate-zip-entry
- Resolve could not find
appcompat-v7: lottie-react-native/lottie-react-native#203 - Connecting the dots between
react-nativeandUnity3D: https://medium.com/codeexplorers/connecting-the-dots-between-react-native-and-unity-3d-using-gradle-67f93b92c254 - Too many field references (aka
DEXlimit): https://stackoverflow.com/questions/42582850/too-many-field-references-70613-max-is-65536 - When to use
gradle.propertiesvssettings.gradle: https://stackoverflow.com/questions/45387971/when-to-use-gradle-properties-vs-settings-gradle React-NativeAndroid app as a Module: http://www.ard.ninja/blog/react-native-android-app-as-a-module/- Yes it is possible to Show
Unity3Din React (different approach): https://medium.com/@beaulieufrancois/show-unity3d-view-in-react-native-application-yes-its-possible-852923389f2d - Crash after requesting
React-NativeBundle :facebook/react-native#10925 aarfile doesn't include transitive dependencies: http://www.riptutorial.com/android-gradle/example/10329/the-aar-file-doesn-t-include-the-transitive-dependenciesandroid:keyboardNavigationClusternot found: https://stackoverflow.com/questions/45301203/no-resource-found-that-matches-the-given-name-attr-androidkeyboardnavigationcReact-Nativedeployment atWalmartLabs: https://medium.com/walmartlabs/react-native-at-walmartlabs-cdd140589560gradleduplicate entry/collide dependencies when enablemultidex: https://stackoverflow.com/questions/28168063/gradle-duplicate-entry-java-util-zip-zipexceptionzipExceptionduplicate entry: http://gurusurend.com/zipexception-duplicate-entry-android-studio/