𦧠please note i haven't been using neither react nor react-unity-webgl in a while so this thing is definitely heavily outdated, good luck!
TLDR; see result here π
- Example project / tutorial for hosting Unity3D WebGL build as a static webpage on Heroku (using create-react-app).
 - Using a super cool repo react-unity-webgl by @El Raccoone
 - Targetted especially for unity3d people who haven't hosted a webapp before.
 
- How to run
 - Initial project setup
 - Build Unity project for WebGL
 - Integrate Unity build into your react webapp
 - Two-way communication
 
You will need to have yarn installed on your pc
$ git clone https://github.com/mariaheine/unity3d-react-boilerplate.git
$ yarn install
$ yarn start
This will let you locally run example project.
π Follow the Quick Start on this repo: Heroku Buildpack for create-react-app With just a few easy steps you end with a static, frontend-only web site hosted on Heroku.
To update the site by pushing changes to heroku remote:
$ git commit -m "wow :o"
$ yarn build
$ git push heroku master
To open it:
`$ heroku open`
Wait what?? And just like that I have hosted a webpage? π° π·
Your package.json should look something like this (no babel, no webpack config π):
{
  "name": "unity3d-react-boilerplate",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-scripts": "1.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}π Unity documentation concerning WebGL development
π§ Your build settings should look something like on the picture below, please pay special attention to:
- Setting build platform for WebGL
- File -> Build Settings -> Platfrom -> WebGL
 
 - ColorSpace
- Changing it from 
GammatoLinearwill force you to use WebGL 2.0 which will unfortunately break compatibility with Safari browsers (as of 16/08/2020 for Safari 12.1), so you should probably keep usingGamma 
 - Changing it from 
 
- π Once building is finished, you should be most interested with a directory containing those files:
 
- 
Add react-unity-webgl into your project, it's just so cool.
 - 
Copy entire Unity build folder (mentioned above) into your
publicwebapp folder. - 
Replace your
App.jswith quick start code from react-unity-webgl 
In case of this example project it would be just:
import React from "react";
import Unity, { UnityContent } from "react-unity-webgl";
export class App extends React.Component {
  constructor(props) {
    super(props);
    this.unityContent = new UnityContent(
      "CookieEater/Build/CookieEater.json.json",
      "CookieEater/Build/UnityLoader.js"
    );
  }
  render() {
    return <Unity unityContent={this.unityContent} />;
  }
}- πΌ After these easy steps you should be ready to test your Unity webapp by simply running 
$ yarn startcommand in your console. Uploading to Heroku is just as easy using 
With barely 5 lines of code your Unity build is imported and served in your React app. Isn't that cool? :o
For more info about <UnityContent/> component check out Mr. Lanters' github wiki
- π± Calling Unity method with no parameters
 
You can now evoke any public method in your Unity project by sending a message to unityContent specifying:
a. A GameObject name that has a MonoBehaviour attached
b. A name of a public method within one of the attached MonoBehaviours
this.unityContent.send(
  "FlyCube", // GameObject name
  "Randomize" // Public method name
);- πΏ Calling Unity method with a single parameter
 
this.props.unityContent.send("PlayArea", "SpawnCube", 10);let mouseCoords = `${this.state.pageX} ${this.state.pageY}`;
if (this.state.isLoaded === true) {
  this.unityContent.send(
    "TextDisplayer",
    "UpdateDoubleMousePosition",
    mouseCoords
  );
}- π΄ Calling a method with more than one parameter - possible workaround.
 
As mentioned above GameObject.SendMessage(), here as this.unityContent.send(...), may only pass as value one argument that can be either a number or a string.
One possible workaround is passing multiple values in a string and then parsing it inside Unity method.
In above mouseCoords string variable to a method UpdateDoubleMousePosition inside TextDisplayer GameObject. To interpret that string as two separate numbers in C#:
public void UpdateDoubleMousePosition(string mouseCoords)
{
   string[] coords = mouseCoords.Split(' ');
   int[] coordsNumerical = new int[2];
   for(int i = 0; i < coords.Length; i++)
   {
      coordsNumerical[i] = Int32.Parse(coords[i]);
   }
   TextY.text = coords[0];
   TextX.text = coords[1];
}3 steps for every single call:
- pre: creating .jslib plugin
 - Creating javascript event handler
 - Adding the method binding to the .jslib script
 - Importing and using the method binding in a unity c# script
 
Create a text file in Plugins folder in your Unity project (the folder has to be named this way) and rename it to howeveryouwant.jslib,
     
     | 
    
The empty base of that script should look like this:
 | 
  
An example of Score.js from example project:
props.unityContent.on("CookieEatenEvent", () => {
  this.setState((prevState) => ({
    cookiesEaten: prevState.cookiesEaten + 1,
  }));
});mergeInto(LibraryManager.library, {
  CookieEatenEvent: function() {
    ReactUnityWebGL.CookieEatenEvent();
  }
});
From example project:
Read more about Native plugins
public class CookieEaten : MonoBehaviour {
    [DllImport("__Internal")]
    private static extern void CookieEatenEvent();
    void OnTriggerEnter(Collider col)
    {
        // -------------
        
        #if !UNITY_EDITOR && UNITY_WEBGL
            CookieEatenEvent();
        #endif
        Destroy(gameObject);
        
        // -------------
    }
}Thats all, have fun! π



