Search Unity

How to ensure that webgl is loaded and can call SendMessage

Discussion in 'Web' started by Thaina, Mar 29, 2016.

  1. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    I have a callback function in js to login facebook and call SendMessage when login is done. Sometime the login process is finished before webgl and it cause error to call SendMessage

    Are there any callback function that could be use to listen to webgl load finish?
     
  2. Good-old-Grim

    Good-old-Grim

    Joined:
    Jan 17, 2014
    Posts:
    33
    Use Application.ExternalCall to call js from your application.
     
  3. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    I have my callback for login in js too. It need to wait for both. So I need to implement checking for webgl loaded in js
     
  4. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello Thaina.

    This task is not specific to WebGL, but rather it is a common situation when you wait for completion of multiple asynchronous operations in JavaScript. For example, it can be resolved like this:
    Code (JavaScript):
    1.   var dependencies = {
    2.     'facebook_login' : true,
    3.     'webgl_ready' : true,
    4.   };
    5.   function removeDependency(dependency) {
    6.     if (dependencies[dependency])
    7.       delete dependencies[dependency];
    8.     if (!Object.keys(dependencies).length)
    9.       SendMessage('Game','Ready');
    10.   }
    Your facebook login callback should therefore call removeDependency('facebook_login'), and your WebGL application should call removeDependency('webgl_ready') through jslib plugin from, let's say, Game.Start() (note that SendMessage will only work if the referenced game object exists and is active, therefore initialization of WebGL module itself is not sufficient, while execution of Game.Start guarantees that the Game object already exists). When both dependencies get removed, the Game.Ready() method will be executed. Also, if you want to ensure that initialization of all the game objects has been completed at the moment when Game.Ready() method is called, you might consider using setTimeout(function(){SendMessage('Game','Ready')},0) instead, so that it will be called the next frame after initialization.
     
    guneyozsan and Demoralizator like this.
  5. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,166
    @alexsuvorov I am currently do something it like that. But I just think webgl from unity should be smart enough to expose some event callback for notify javascript directly. At least when it finish loaded and ready to call SendMessage

    You see, to just notify unity that player was logged in, it need to implement things in 3 places. If at least we have callback function window.unityLoaded or similar in decrease to just 2 place and decrease so many dependency
     
  6. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    As mentioned above, you have to ensure that the game object referenced in SendMessage has been already created. Game objects can be created dynamically and there is no way for Unity to know which object exactly you are waiting for, unless you are waiting for creation of all the static objects in the scene, but that is rather a specific usecase.
     
    Last edited: Mar 29, 2016
    Thaina likes this.
  7. tonialatalo

    tonialatalo

    Joined:
    Apr 23, 2015
    Posts:
    60
    seems to be fine indeed that we need to tell ourselves from our unity apps when they are ready to for things to be handled with the web side -- now did some scene loading based on url parameters & a bit before also facebook login .. don't need to track dependencies (such as SendMessage) to appear, but just have a call from Unity side from the right spot.

    seemed complex at first but started making sense to me too while making those, for the reason alexsuvorov had apparently posted here. thanks for sharing views all.

    what i started fancying though was something like Application.ExternalCall but a synchronous direct function call that could have return variables. could do things like: string facebook_token = Application.ExternalCallSynchronous("getFacebookToken"); (we give it to playfab sdk in unity then) without needing SendMessage back from the browser js side. the unity app code is just normal js code ran in the browser along the js functions from the html too, why not allow such direct calling too?
     
  8. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    You might consider using a JavaScript plugin instead of the Application.ExternalCall. Not only because it will automatically solve you problem (you can get a return value from the executed JavaScript code), but also because ExternalCall is internally using JavaScript eval, which is a subject of security restrictions in specific environments (i.e. Chrome packaged app). Check out the StringReturnValueFunction function at the following link https://docs.unity3d.com/Manual/webgl-interactingwithbrowserscripting.html

    Moreover, you are also able to synchronously return a value from a C# function to JavaScript. This is not as convenient as another direction of course, but still possible. The trick is that, unlike some other platforms, in WebGL the SendMessage is executed synchronously, so you can use a helper function and a JavaScript context variable to synchronously return a value back to JavaScript. Check out the following reply for a working example https://forum.unity3d.com/threads/super-fast-javascript-interaction-on-webgl.382734/#post-2573686
     
    tonialatalo and Zaelot like this.