
Note: The yellow console warnings are coming from the Unity scene.
It may not work with the native OnApplicationQuit
, but it is possible. You can do this using a custom WebGL Template.
Before you start reading, it might be a good idea to glance over the Unity Documentation on Interacting with Browser Scripting.
Setting up your WebGL Template
First, you’ll want to create a WebGL template to use for your project. Read through that guide to learn how to create one. Once that’s done, you’ll have something in a <script>
tag that looks like this:
gameInstance = UnityLoader.instantiate("gameContainer", "%UNITY_WEBGL_BUILD_URL%", {});
You’ll use this object to communicate with your Unity Scene, as it can use the well-known SendMessage
function. For now, paste this below that UnityLoader.instantiate
line in your template:
// Callback for the Unity OnClose event
window.onbeforeunload = function(e) {
// These are the messages you're seeing in the gif
console.log("Calling OnClose from Browser!");
gameInstance.SendMessage("OnCloseObject", "OnClose");
// 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;
};
As of right now, your Unity’s browser will try to call functions in Unity that don’t exist yet, so let’s set those up now.
Setting up your Scene
In my example, I made a simple object named OnCloseObject
with a single script given below:
using UnityEngine;
using UnityEngine.UI;
public class OnCloseListener : MonoBehaviour
{
public Image backgroundImage;
/// <summary>
/// Called when the Browser is closed.
/// </summary>
public void OnClose()
{
// Uncomment this if you set up Interop
//BrowserJS.Warn("This warning was called from Unity!");
// Randomize the background image color
this.backgroundImage.color = new Color(Random.value, Random.value, Random.value);
}
}
If you don’t want to set up the Interop stuff for Unity to speak to the browser, skip the next part.
(Optional) Setting up Interop
Create a folder called Plugins
in your project and add the following as plugins.jslib
:
mergeInto(LibraryManager.library, {
Alert: function (str) {
window.alert(Pointer_stringify(str));
},
Console: function (str) {
console.log(Pointer_stringify(str));
},
Warn: function (str) {
console.warn(Pointer_stringify(str));
},
Error: function (str) {
console.error(Pointer_stringify(str));
}
});
Then, create a new script and paste this:
using System.Runtime.InteropServices;
public class BrowserJS
{
[DllImport("__Internal")]
public static extern void Alert(string str);
[DllImport("__Internal")]
public static extern void Log(string str);
[DllImport("__Internal")]
public static extern void Warn(string str);
[DllImport("__Internal")]
public static extern void Error(string str);
}
Once this is in place and your WebGL build is using your modified Template, you should be ready to go.
There might be some race conditions if your save process is a bit lengthy and the user closes out too quickly? I am sure there are some nuance-y things I am missing here, but this should be enough to get you started.