Search Unity

WebGL Fix Firefox crashing on closing the page?

Discussion in '5.3 Beta' started by heroichippo1, Nov 23, 2015.

  1. heroichippo1

    heroichippo1

    Joined:
    Mar 30, 2015
    Posts:
    36
    Hello,

    In Unity 5.1 & 5.2, OnApplicationQuit wasn't being called in WebGL. There also was a giant crashing error message whenever the user navigated away from the page in both Chrome and Firefox.

    I had used a workaround of overriding the window.onbeforeunload event in javascript, and calling setTimeout(250) and using that time to SendMessage back into unity and do my logic there which included waiting for a WWW request to save my players progress to our backend.

    Since updating to 5.3f1, this workaround doesn't seem to work anymore. i'm curious if there was a change made that to fix that crash in firefox overrides the window.onbeforeunload event which is causing my code to not run.

    If that is the case, what changes were made so I can get back to saving my progress in OnApplicationQuit
     
  2. heroichippo1

    heroichippo1

    Joined:
    Mar 30, 2015
    Posts:
    36
    Here's a code stub for what i was doing and is no longer working.

    Code (CSharp):
    1. // Use this for initialization
    2.     void Start () {
    3.         // DO NOT REMOVE THIS STOPS A MASSIVE ERROR MESSAGE FROM POPING UP ON THE SCREEN WHEN THE USER UNLOADS TEH PAGE
    4.         Application.ExternalEval(@"
    5.                function OnMyApplicationQuit(e)
    6.                {
    7.                    SendMessage('" + gameObject.name + @"', 'OnApplicationQuit', '');
    8.                    setTimeout(250);
    9.                    return;
    10.                }
    11.                window.onbeforeunload = OnMyApplicationQuit;
    12.            "
    13.             );
    14.     }
    15.     public void OnApplicationQuit()
    16.     {
    17.         if(GameController.Instance != null)
    18.             GameController.Instance.OnApplicationQuit();
    19.     }
     
  3. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,574
    Hey. We have indeed changed the window.onbeforeunload usage in 5.3, though I don't understand why it affects you.

    In 5.2, we did actually set up window.onbeforeunload to properly shut down the engine and call OnApplicationQuit in Unity. It turned out that there were some problem with this approach:

    -Some people wanted to set up window.onbeforeunload themselves in JS to do a handler which would allow the user to cancel closing the page (which browsers will automatically do when you return a value from onbeforeunload). This would interfere with us using onbeforeunload. We considered calling existing handlers from ours, but there is an issue with that as well, because there is no way to know if closing is cancelled by the user or not. So we might end up shutting down the engine, when the user would cancel closing the page.

    -The main (only?) use for OnApplicationQuit in Unity WebGL is to persist some data before the player shuts down. However, we found out that it is not possible to do this in onbeforeunload and rely on it to work. Because any API to persist data in JavaScript (either locally in IndexedDB or remotely through network access) is asynchronous, and there is no guarantee that it would indeed succeed before it is terminated. We have tried this and indeed found cases where behavior was indeterministic and data was sometimes saved and sometimes lost. So supporting OnApplicationQuit gives people a false sense of security that data is not lost, when they cannot actually rely on it.

    For these reasons we have decided not to use onbeforeunload in 5.3, and not to call OnApplicationQuit.

    If you need to save data, you should either do so in regular intervals, or allow the user to cancel exiting the page (by returning a value onbeforeunload) if there is unsaved data.

    If you are using onbeforeunload to avoid crashes, then we should just fix those crashes. Please report them as bugs with repro cases (and send me the case numbers).

    Finally, FYI, I don't believe that the setTimeout in your code snippet has any effect - the first parameter of setTimeout should be a function to be called after a timeout.