Live Example: https://unityreactbridge.netlify.app/
This repo holds an example project of a React Web App that contains a Unity WebGL build. Fruit is dropped in the Unity app via a React button (React -> Unity communication example). When a fruit is clicked, the item is added to the React Inventory (Unity -> React communication example). To demonstrate passing properties, when the 'Sell Fruit' button is clicked in React, the value updates in the Unity app.
This document outlines the process of integrating a Unity WebGL build into a React application. It covers:
- Embedding a Unity WebGL instance in a React component.
- Sending messages from React to Unity.
- Receiving messages from Unity to React.
This guide provides a reusable template that other developers can follow to integrate Unity WebGL into their projects.
To integrate Unity WebGL into a React app, follow these steps:
- Open Unity and navigate to
File > Build Settings
. - Select WebGL as the target platform.
- Configure build settings to ensure compression and proper loading:
- Enable
Development Build
(for debugging, optional for production). - Set compression format to
Gzip
orBrotli
(to reduce file size). - Set
Data Caching
enabled (for performance).
- Enable
- Click Build and place the generated files in a
/Build
directory within the React project.
The following React component loads the Unity WebGL build and enables communication between React and Unity.
import { useEffect, useRef } from "react";
const UnityComponent = () => {
const unityRef = useRef<HTMLDivElement>(null);
const [unityInstance, setUnityInstance] = useState<any>(null);
// Set up the canvas and Unity Instance
useEffect(() => {
if (!unityRef.current) return;
// Create and append Unity canvas
const canvas = document.createElement("canvas");
canvas.id = "unity-canvas";
canvas.style.width = "100%";
canvas.style.height = "100%";
unityRef.current.appendChild(canvas);
// Load Unity WebGL script
const script = document.createElement("script");
script.src = "/Build/UnityBuild.loader.js"; // Update with correct path
script.onload = () => {
(window as any)
.createUnityInstance(canvas, {
dataUrl: "/Build/UnityBuild.data.gz",
frameworkUrl: "/Build/UnityBuild.framework.js.gz",
codeUrl: "/Build/UnityBuild.wasm.gz",
streamingAssetsUrl: "/StreamingAssets",
companyName: "YourCompany",
productName: "YourGame",
productVersion: "1.0",
})
.then((instance: any) => {
console.log("Unity Loaded!", instance);
setUnityInstance(instance);
})
.catch((error: any) => {
console.error("Unity loading failed:", error);
});
};
document.body.appendChild(script);
}, []);
// Unity message calls (for React -> Unity comms)
useEffect(() => {
if (!unityInstance) return;
const sendMessageToUnity = () => {
unityInstance.SendMessage("GameObjectName", "UnityMethod");
};
const sendMessageWithParam = (param: string) => {
unityInstance.SendMessage("GameObjectName", "UnityMethod", param);
};
// Expose these functions globally if needed
(window as any).sendMessageToUnity = sendMessageToUnity;
(window as any).sendMessageWithParam = sendMessageWithParam;
}, [unityInstance]); // Runs when `unityInstance` is set
return (
<Container>
<h2>React ↔️ Unity WebGL</h2>
<Content>
<div ref={unityRef} style={{ width: "550px", height: "800px", margin: "auto" }} />
<button onClick={() => (window as any).sendMessageToUnity?.()}>Send Message to Unity</button>
<button onClick={() => (window as any).sendMessageWithParam?.("Hello Unity!")}>
Send Message with Param
</button>
</Content>
</Container>
);
};
export default UnityComponent;
To communicate with Unity, use SendMessage
:
if ((window as any).unityInstance) {
(window as any).unityInstance.SendMessage("GameObjectName", "UnityMethod", "OptionalParameter");
}
Ensure the Unity GameObject has a script that listens for messages:
using UnityEngine;
public class UnityReceiver : MonoBehaviour {
public void UnityMethod(string message) {
Debug.Log("Received message from React: " + message);
}
}
Unity can call JavaScript functions using window
:
using UnityEngine;
public class UnityToReact : MonoBehaviour {
void SendDataToReact() {
Application.ExternalCall("ReactFunction", "Hello from Unity!");
}
}
In React, define a global function:
useEffect(() => {
(window as any).ReactFunction = (message: string) => {
console.log("Received from Unity:", message);
};
}, []);
- Check the file paths for
loader.js
,framework.js
, andwasm.gz
. - Open the browser console (
F12
> Console) for errors. - The server may not be handling compression correctly. See header files in example project. These tell the server to serve the compressed Unity files correctly.
- Ensure the GameObject name in
SendMessage
matches the Unity hierarchy. - Make sure the Unity method is public.
- If using
Application.ExternalCall
, enable WebGL templates that support JavaScript calls.
This document provides:
- A React component to embed Unity WebGL.
- Methods for React ↔ Unity communication.
- Debugging tips for common issues.
Following these steps, other developers can seamlessly integrate Unity WebGL into React applications.