The plugin that allows you to embed a UNITY project into the react native as a full-fledged component
npm install @azesmway/react-native-unity
or
yarn add @azesmway/react-native-unity- Copy from folder "unity" to <Unity_Project_Name> folder and rebuild unity project.
Add this code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine.UI;
using UnityEngine;
public class NativeAPI {
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
public static extern void sendMessageToMobileApp(string message);
#endif
}
public class ButtonBehavior : MonoBehaviour
{
public void ButtonPressed()
{
if (Application.platform == RuntimePlatform.Android)
{
using (AndroidJavaClass jc = new AndroidJavaClass("com.azesmwayreactnativeunity.ReactNativeUnityViewManager"))
{
jc.CallStatic("sendMessageToMobileApp", "The button has been tapped!");
}
}
else if (Application.platform == RuntimePlatform.IPhonePlayer)
{
#if UNITY_IOS && !UNITY_EDITOR
NativeAPI.sendMessageToMobileApp("The button has been tapped!");
#endif
}
}
}- Build Unity app to
[project_root]/unity/builds/ios - Add
Unity-iPhone.xcodeprojto your XCode: press the right mouse button in the Left Navigator XCode ->Add Files to [project_name]...->[project_root]/unity/builds/ios/Unity-iPhone.xcodeproj - Add
UnityFramework.frameworktoGeneral/ sectionFrameworks, Libraries, and Embedded Content - Select Data folder and set a checkbox in the "Target Membership" section to "UnityFramework"
- You need to select the NativeCallProxy.h inside the
Unity-iPhone/Libraries/Plugins/iOSfolder of the Unity-iPhone project and change UnityFramework’s target membership from Project to Public. Don’t forget this step! https://miro.medium.com/max/1400/1*6v9KfxzR6olQNioUp_dFQQ.png - In
Build Phasesremove UnityFramework.framework fromLinked Binary With Libraries - In Build Phases move Embedded Frameworks before Compile Sources ( drag and drop )
-
Export Unity app to
[project_root]/unity/builds/android -
Add the following lines to
android/settings.gradle:include ':unityLibrary' project(':unityLibrary').projectDir=new File('..\\unity\\builds\\android\\unityLibrary')
-
Add into
android/build.gradleallprojects { repositories { // this flatDir { dirs "${project(':unityLibrary').projectDir}/libs" } // ...
-
Add into
android/gradle.propertiesunityStreamingAssets=.unity3d
-
Add strings to
android/app/src/main/res/values/strings.xml<string name="game_view_content_description">Game view</string>
-
Remove
<intent-filter>...</intent-filter>from<project_name>/unity/builds/android/unityLibrary/src/main/AndroidManifest.xmlat unityLibrary to leave only integrated version.
- Works only on real iOS devices. Android emulators are capable of showing the UnityView.
- On IOS the Unity view is waiting for a parent with dimensions greater than 0 (from RN side). Please take care of this because if it is not the case, your app will crash with the native message
MTLTextureDescriptor has width of zero.
import React, { useRef, useEffect } from 'react';
import UnityView from '@azesmway/react-native-unity';
import { View } from 'react-native';
interface IMessage {
gameObject: string;
methodName: string;
message: string;
}
const Unity = () => {
const unityRef = useRef<UnityView>(null);
useEffect(() => {
if (unityRef?.current) {
const message: IMessage = {
gameObject: 'gameObject',
methodName: 'methodName',
message: 'message',
};
unityRef.current.postMessage(message.gameObject, message.methodName, message.message);
}
}, []);
return (
<View style={{ flex: 1 }}>
<UnityView
ref={unityRef}
style={{ flex: 1 }}
onUnityMessage={(result) => {
console.log('onUnityMessage', result.nativeEvent.message)
}}
/>
</View>
);
};
export default Unity;androidKeepPlayerMounted?: boolean- if set to true, keep the player mounted even when the view that contains it has lost focus. The player will be paused on blur and resumed on focus. FOR ANDROID: has no effect on iOS.fullScreen?: boolean- defaults to true. If set to false, will not request full screen access. ANDROID ONLYonUnityMessage?: (event: NativeSyntheticEvent)- receives a message from a Unitystyle: ViewStyle- styles the UnityView. (Won't show on Android without dimensions. Recommended to give itflex: 1as in the example)
-
postMessage(gameObject, methodName, message)- sends a message to the Unity. FOR IOS: The native method of unity is used to send a messagesendMessageToGOWithName:(const char*)goName functionName:(const char*)name message:(const char*)msg;, more details can be found in the documentation -
unloadUnity()- the Unity is unloaded automatically when the react-native component is unmounted, but if you want to unload the Unity, you can call this method -
pauseUnity?: (pause: boolean)- pause the Unity
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT