Unity 2020.1 sendMessage no longer works. Help

The new version does not have instantiate in the .js file.
There is no this line

var unityInstance = UnityLoader.instantiate("unityContainer", "Build/YourBuild.json", {onProgress: UnityProgress});

If I try unityInstance.SendMessage("ObjectName","methodname",value);
The console in brower reports unityInstance not defined.

How do I send message from browser to webgl now?

It has changed to the following signature:

function createUnityInstance(canvas, config, onProgress) {
  ...
}

The template has been changed to:

createUnityInstance(document.querySelector("#unity-canvas"), {
        dataUrl: "...",
        frameworkUrl: "...",
        codeUrl: "...",
        streamingAssetsUrl: "...",
        companyName: "...",
        productName: "...",
        productVersion: "...",
      });

This means only the function “createUnityInstance” will now be visible as global, and you need to instantiate your own “unityInstance” variable with it. Also note it now requires the canvas object to be passed instead of the id.

Thank you. But how exactly do I instantiate with createUnityInstance? I tried to put a “var unityInstance =” infront of it in the index.html. but then it reports sendMessage is not a function.

It’s usually a good idea to log the objects you’re creating when you’re exploring. Try putting in a “console.log(unityInstance)”. I believe it’s either under the Module object, or it should be capitalised as “SendMessage”. Just log it in the console and explore the object, you should see it somewhere in there.

Here is the log, and I did
var unityInstance = createUnityInstance…
console.log(unityInstance)
Please help, I don’t understand, I see SendMessage right there, and I tried “SendMessage” with captial S, doesn’t work either.

5563042--573499--Annotation 2020-03-08 110855.jpg

createUnityInstance now returns a Promise, you need to add “.then((unityInstance) => {… do something with it …})” after it and continue a chain from there. More info on promises can be found here: JavaScript Promises: an introduction  |  Articles  |  web.dev.

The reason you’re seeing the object function, but it says undefined when logging is because promises do not resolve immediately. If you log the variable immediately after the promise, it will be undefined as the Promise has not resolved yet. It will show up in the console, but with a small “i” next to it which will indicate the browser “filled it in when it eventually became available afterwards”. It’s a useful browser feature which can surely trip you up if you don’t understand how promises work.

See this link for all other info on how to migrate: Changes to the WebGL loader and templates introduced in Unity 2020.1

2 Likes

Works fine now. Thank you so much for your help. I understand it’s alpha, but the document for 2020.1 on unity website isn’t updated for this yet.

Can you post your solution. It will help a lot of people when they will use this version of Unity.
Thank you

1 Like
var gameInstance = createUnityInstance(..........
gameInstance.then((unityInstance) => {
            unityInstance.SendMessage("GameObject","method",value);        
        });
4 Likes

How do you now handle the new onProgress callback, @harrywenjie ? :x
Before it was just { onProgress : UnityProgress }

<!DOCTYPE html>
<html lang="en-us">
   <head>
      <meta charset="utf-8">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Unity WebGL Player | V Combined Meeting e Four Otology</title>
      <link rel="shortcut icon" href="TemplateData/favicon.ico">
      <link rel="stylesheet" href="TemplateData/style.css">
   </head>
   <body>
      <div id="unity-container" class="unity-desktop">
         <canvas id="unity-canvas"></canvas>
         <div id="unity-loading-bar">
            <div id="unity-logo"></div>
            <div id="unity-progress-bar-empty">
               <div id="unity-progress-bar-full"></div>
            </div>
         </div>
         <div id="unity-footer">
            <div id="unity-webgl-logo"></div>
            <div id="unity-fullscreen-button"></div>
            <div id="unity-build-title">V Combined Meeting e Four Otology</div>
         </div>
      </div>
      <script>
         var buildUrl = "Build";
         var loaderUrl = buildUrl + "/build.loader.js";
         var config = {
           dataUrl: buildUrl + "/build.data.unityweb",
           frameworkUrl: buildUrl + "/build.framework.js.unityweb",
           codeUrl: buildUrl + "/build.wasm.unityweb",
           streamingAssetsUrl: "StreamingAssets",
           companyName: "Casa Mais",
           productName: "V Combined Meeting e Four Otology",
           productVersion: "1.0",
         };
        
         var container = document.querySelector("#unity-container");
         var canvas = document.querySelector("#unity-canvas");
         var loadingBar = document.querySelector("#unity-loading-bar");
         var progressBarFull = document.querySelector("#unity-progress-bar-full");
         var fullscreenButton = document.querySelector("#unity-fullscreen-button");
        
         if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
           container.className = "unity-mobile";
           config.devicePixelRatio = 1;
         } else {
           canvas.style.width = "960px";
           canvas.style.height = "600px";
         }
         loadingBar.style.display = "block";
        
         var script = document.createElement("script");
         script.src = loaderUrl;
         script.onload = () => {
           window.gameInstance = createUnityInstance(canvas, config, (progress) => {
             progressBarFull.style.width = 100 * progress + "%";
           }).then((unityInstance) => {
             loadingBar.style.display = "none";
             fullscreenButton.onclick = () => {
               unityInstance.SetFullscreen(1);
             };
           }).catch((message) => {
             alert(message);
           });
         };
         document.body.appendChild(script);
      </script>
      <script>
         // Callback for the Unity OnClose event
         window.onbeforeunload = function(e) {
        
         e.preventDefault();
         // These are the messages you're seeing in the gif
         console.log("Calling OnClose from Browser!");
        
        
         gameInstance.then((unityInstance) => {
         unityInstance.SendMessage("OnCloseObject","OnClose");       <<< this is line 79
         });
        
         // This never shows up correctly for me, but it does prompt
         // the player to close their window with a dialogue box
         //
         var dialogText = "You game has been saved!  Would you like to continue unloading the page?";
         e.returnValue = dialogText;
         return dialogText;
         };   
      </script>
   </body>
</html>

Guys, heres my index.html of the webgl build. When i close the browser i want to have a function activated on unity side. Its giving me this error >>>

Uncaught (in promise) TypeError: unityInstance is undefined
onbeforeunload https://www.plataformareuni.com.br/v-combined-meeting-e-four-otology/:79

Dunno whats wrong. Can anyone help?

@harrywenjie can u help?

There is an easy solution.
It’s a matter of storing the unityInstance object in a window variable that you can latter use. The best moment to do that is right after the onload gets set, at the beginning of the “then”. So:

script.onload = () => {
           window.gameInstance = createUnityInstance(canvas, config, (progress) => {
             progressBarFull.style.width = 100 * progress + "%";
           }).then((unityInstance) => {
             window.gameInstance = unityInstance; //This is where you store the object
             loadingBar.style.display = "none";
             fullscreenButton.onclick = () => {
               unityInstance.SetFullscreen(1);
             };

You can then send messages at a later time with
gameInstance.SendMessage(GameObject_name, Method_name,value)

You can even use this variable inside the .jslib plugins. So that events that respond to the changes in the browser may interact with objects inside the unityInstance object.

2 Likes

Hi

I tried this solution for my application but the application never executed the “.then” part. Does it take longer to get it executed?