Search Unity

Question WebGL JavaScript to Unity

Discussion in 'Web' started by saifshk17, Feb 8, 2023.

  1. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    488
    I am trying to understand from here - https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html how we can trigger a js function from Unity.

    I have followed that and edited my html file such as:

    Code (CSharp):
    1.  
    2. var myGameInstance = null;
    3.      var script = document.createElement("script");
    4.      script.src = loaderUrl;
    5.      script.onload = () => {
    6.        createUnityInstance(canvas, config, (progress) => {
    7.          progressBarFull.style.width = 100 * progress + "%";
    8.        }).then((unityInstance) => {
    9.          myGameInstance = unityInstance;
    10.          loadingBar.style.display = "none";
    11.        }).catch((message) => {
    12.          alert(message);
    13.        });
    14.      };
    15.    
    16.  
    17.      function CheckAlert() {
    18.        alert("MessageReceived");
    19.      }
    20.  
    and my C# code is as:

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using System.Runtime.InteropServices;
    6.  
    7. public class Bridge : MonoBehaviour
    8. {
    9.  
    10. #if UNITY_WEBGL && !UNITY_EDITOR
    11.    [DllImport("__Internal")]
    12.    private static extern void SendMessage(string message);
    13. #endif
    14.  
    15.    void Start () {
    16.      Invoke("SendToJS", 2.0f);
    17.    }
    18.  
    19.    public void SendToJS () {
    20.        Debug.Log ("Sending message to JavaScript");
    21. #if UNITY_WEBGL && !UNITY_EDITOR
    22.        SendMessage ("Ok");
    23. #endif
    24.    }
    25. }
    26.  
    and my js.jslib library is as follows:

    Code (CSharp):
    1.  
    2. mergeInto(LibraryManager.library, {
    3.  
    4.    SendMessage: function (message) {
    5.        CheckAlert();
    6.    },
    7.  
    8. });
    9.  
    But unfortunately nothing gets sent through, I never receive an alert message which I should.

    How do I fix this?
     
    Last edited: Feb 8, 2023
  2. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    I notice is that your variable has a lower case "m" in "myGameInstance".. whereas your CallToUnity function expects it to be upper case.. "MyGameInstance".
     
    CodeSmile likes this.
  3. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    488
    Hey that was an error from my side. I have updated my question. Please take a look at this.
     
  4. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    The new issue you're mentioning is easiest to work around by using window., for example,
    window.CheckAlert = function(){ alert("MessageReceived"); }
    . Then in your jslib, say
    window.CheckAlert();
    ..at least, this approach has solved the same kind of issue for me anyway.

    Something else to be wary of in your original post.. in case you still do it, you were expecting the game has always finished loading within 5 seconds. Your timeout may fire before the game has loaded though, in which case that would also likely throw an exception. You could move your setTimeout into the "then" part of your loading, so it doesn't start counting down until the game has loaded first.
     
    saifshk17 likes this.
  5. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    488
    Thank you i will try that out.
    Then how would i know if my game has finished loading?
     
  6. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    The place where it says
    loadingBar.style.display = "none";
    is where it hides the loading bar because the game has finished loading, so anywhere immediately before or after that line should be appropriate. However, you might want to do it from C# instead (through your .jslib) to be sure any in-game initialization has been done beforehand as well. Otherwise there's still a chance the game has loaded but maybe the browser has lost focus of the tab/window and stops processing it at the rate you're expecting, or the Unity logo is still displaying because some kind of other initialization took a bit longer than expected.. etc.
     
    saifshk17 likes this.
  7. saifshk17

    saifshk17

    Joined:
    Dec 4, 2016
    Posts:
    488
    Thank you, that worked :)
    I have one more query, how do I access JavaScript modules and its events from Unity?
     
  8. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    Depends on what exactly you want to do - you could search for examples of how to do that in particular.. but if you want C# functions to be called from events in JavaScript, as far as I know you have to add your listeners in JS then use SendMessage from those. You can add those listeners either in your page or in your .jslib, for example if you wanted to listen for a click event on a specific DOM element. Given the choice, keeping as much in the .jslib as possible helps make it easier to switch between templates without breaking things. You can access whatever scripts are loaded in the page from your .jslib the same way as usual, but might find it doesn't always work (or work the same) without adding window. before some things. For example in the page, maybe you call eval(some_js_code), but in .jslib you would need to say window.eval(some_js_code) or it won't execute within the expected scope.

    Edit: Also, one last tip.. if you're going to add lots of functions and data to window, you might consider creating an object to hold all of that, i.e. at startup, window.mydata = {}; then later you do like window.mydata.something =.. instead of directly like window.something =.. This way it's much easier to debug with console (you can just type "window.mydata." and it auto-suggests/drops down a list showing all the stuff you've added), also this way keeps the window object tidy and makes resetting/clearing your extra stuff easy by just setting window.mydata = {} again :)
     
    Last edited: Feb 8, 2023
    saifshk17 likes this.