Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Calling Unity scripts functions from JavaScript

I am attempting to call a unity script from JS but there is no MyGameInstance as seen in the Unity Documentation: https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html

Here is a slightly modified (removed the footer) version of the html that WebGL produced by Unity’s Run and Build function:

<!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 | communication</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" width=960 height=600></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-warning"> </div>
      <input type="checkbox">
    </div>
    <script>
      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 warningBanner = document.querySelector("#unity-warning");

      // Shows a temporary message banner/ribbon for a few seconds, or
      // a permanent error message on top of the canvas if type=='error'.
      // If type=='warning', a yellow highlight color is used.
      // Modify or remove this function to customize the visually presented
      // way that non-critical warnings and error messages are presented to the
      // user.
      function unityShowBanner(msg, type) {
        function updateBannerVisibility() {
          warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
        }
        var div = document.createElement('div');
        div.innerHTML = msg;
        warningBanner.appendChild(div);
        if (type == 'error') div.style = 'background: red; padding: 10px;';
        else {
          if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
          setTimeout(function() {
            warningBanner.removeChild(div);
            updateBannerVisibility();
          }, 5000);
        }
        updateBannerVisibility();
      }

      var buildUrl = "Build";
      var loaderUrl = buildUrl + "/webgl.loader.js";
      var config = {
        dataUrl: buildUrl + "/webgl.data.br",
        frameworkUrl: buildUrl + "/webgl.framework.js.br",
        codeUrl: buildUrl + "/webgl.wasm.br",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "DefaultCompany",
        productName: "communication",
        productVersion: "1.0",
        showBanner: unityShowBanner,
      };

      // By default Unity keeps WebGL canvas render target size matched with
      // the DOM size of the canvas element (scaled by window.devicePixelRatio)
      // Set this to false if you want to decouple this synchronization from
      // happening inside the engine, and you would instead like to size up
      // the canvas DOM size and WebGL render target sizes yourself.
      // config.matchWebGLToCanvasSize = false;

      if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
        container.className = "unity-mobile";
        // Avoid draining fillrate performance on mobile devices,
        // and default/override low DPI mode on mobile browsers.
        config.devicePixelRatio = 1;
        unityShowBanner('WebGL builds are not supported on mobile devices.');
      } else {
        canvas.style.width = "960px";
        canvas.style.height = "600px";
      }
      loadingBar.style.display = "block";

      var script = document.createElement("script");
      script.src = loaderUrl;
      script.onload = () => {
        createUnityInstance(canvas, config, (progress) => {
          progressBarFull.style.width = 100 * progress + "%";
        }).then((unityInstance) => {
          loadingBar.style.display = "none";
        }).catch((message) => {
          alert(message);
        });
      };

      document.body.appendChild(script);

    </script>
  </body>
</html>

I am trying to call the control function in the following script:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class onoff : MonoBehaviour
{
    public GameObject square;

    public void ctrl(string text) {
        if (text == "0") {
            square.SetActive(false);
        }
        if (text == "1") {
            square.SetActive(true);
        }
    }
}

This is the format of the SendMessage comamnd I have been attempting to do: MyGameInstance.SendMessage('Main Camera', 'ctrl', '0');

>Solution :

In the createUnityInstance.then method, under loadingBar.style.display = "none";, you should be able to put the SendMessage call. Be sure to replace MyGameInstance with unityInstance.

createUnityInstance(canvas, config, (progress) => {
  progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
  loadingBar.style.display = "none";
  unityInstance.SendMessage('Main Camera', 'ctrl', '0');
})

To continue using unityInstance throughout your code, there are two methods.

  1. Use const instance = await createUnityInstance(...); and make the outer function async
  2. Set instance in .then

Here is the code for the first option:

script.onload = async () => {
 const intance = createUnityInstance(canvas, config, (progress) => {
   progressBarFull.style.width = 100 * progress + "%";
 }).then((unityInstance) => {
   loadingBar.style.display = "none";
 }).catch((message) => {
   alert(message);
 });

 instance.SendMessage('Main Camera', 'ctrl', '0');
};

Code for the second option:

.then((unityInstance) => {
  instance = unityInstance;
})

Note that instance is defined outside .then.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading