WebGL:与浏览器脚本交互
WebGL 中的光标锁定和全屏模式

使用 WebGL 模板

When you build a WebGL project, Unity embeds the player in an HTML page so that it can be played in the browser. The default page is a simple white page with a loading bar on a grey canvas. Alternatively, you can select a minimal template (with only the necessary boilerplate code to run the WebGL content) in the Player settings (menu: Edit > Project Settings, then select the Player category).

The built-in HTML pages are fine for testing and demonstrating a minimal Player, but for production purposes, it is often good to see the Player hosted in the page where it will eventually be deployed. For example, if the Unity content interacts with other elements in the page via the external call interface then it must be tested with a page that provides those interacting elements. Unity allows you to supply your own pages to host the Player by using WebGL templates.

WebGL 模板的结构

将自定义模板添加到项目中的方法是在 Assets 文件夹中创建名为“WebGLTemplates”的文件夹,并且模板本身将作为此文件夹中的子文件夹。每个模板文件夹都包含一个 index.html 文件以及页面所需的任何其他资源,例如图像或样式表。

Once created, the template appears among the options on the Player settings. The name of the template is the same as its folder. Optionally, the folder can contain a file named thumbnail.png, which should have dimensions of 128x128 pixels. The thumbnail image is displayed in the inspector to hint at what the finished page will look like.

该 html 文件至少需要包含以下元素:

  • Unity WebGL 加载程序的脚本标记: <script src="%UNITY_WEBGL_LOADER_URL%"></script>

  • Script for instantiating Unity: <script> var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%");</script>

  • A <div> tag, which has an id that is used in the instantiation function. The contents of this div will be replaced with the Unity instance.

UnityLoader.instantiate(container, url, override)

UnityLoader.instantiate 负责创建内容的新实例。

  • container can be either a DOM element (normally a <div> element) or an id of a DOM element. If the DOM element is provided, then the Unity runtime will be instantiated immediately. If an id of a DOM element is provided, then the Unity runtime will be instantiated after the whole document is parsed (which means you can provide an id of a DOM element which has not yet been created at the time of UnityLoader.instantiate() call).

  • url 指定 json 文件的地址,此文件包含有关构建的信息(可使用 %UNITY_WEBGL_BUILD_URL% 变量,构建时会自动解析该变量)。

  • override is an optional parameter which can be used to override the default properties of the instance. For example, you can override the compatibilityCheck, onProgress and popup functions, as those are properties of the instance. Note that Module is a property of the instance as well, so the properties of the Module can be overridden at instantiation time too. Consider the following example:

UnityLoader.instantiate("MyContainer", "%UNITY_WEBGL_BUILD_URL%", {
  compatibilityCheck: function (unityInstance, onsuccess, onerror) {
    if (!UnityLoader.SystemInfo.hasWebGL) {
      unityInstance.popup("Your browser does not support WebGL",
        [{text: "OK", callback: onerror}]);
    } else if (UnityLoader.SystemInfo.mobile) {
      unityInstance.popup("Please note that Unity WebGL is not currently supported on mobiles. Press OK if you wish to continue anyway.",
        [{text: "OK", callback: onsuccess}]);
    } else if (["Edge", "Firefox", "Chrome", "Safari"].indexOf(UnityLoader.SystemInfo.browser) == -1) {
      unityInstance.popup("Please note that your browser is not currently supported for this Unity WebGL content. Press OK if you wish to continue anyway.",
        [{text: "OK", callback: onsuccess}]);
    } else {
      onsuccess();
    }
  },
  onProgress: MyProgressFunction,
  Module: {
    onRuntimeInitialized: MyInitializationCallbackFunction,
  },
});

模板标签

在构建过程中,Unity 会在页面文本中查找特殊标签字符串,并将这些字符串替换为 Editor 提供的值。这些字符串包括名称、屏幕尺寸以及有关播放器的其他有用信息。

Tags are delimited by percent signs (%) in the page source. For example, if the product name is defined as MyPlayer in the Player settings:

<title>%UNITY_WEB_NAME%</title>

将在该构建生成的主机页面中使用

<title>MyPlayer</title>

…in the host page generated for the build. The complete set of tags is given below:

  • __UNITY_WEB_NAME__:播放器的名称。

  • __UNITY_WEBGL_LOADER_URL__:UnityLoader.js 脚本的 URL,该脚本用于执行构建的实例化。

  • __UNITY_WEBGL_BUILD_URL__:JSON 文件的 URL,该文件包含有关构建的所有必要信息。

  • UNITY_WIDTH 和 __UNITY_HEIGHT__:播放器的屏幕宽度和高度(以像素为单位)。

  • UNITY_CUSTOM_SOME_TAG: If you add a tag to the index file in the form UNITY_CUSTOM_XXX, then this tag will appear in the Player settings when your template is selected. For example, if you add &lt;title&gt;Unity Player | %UNITY_CUSTOM_MYTAG%&lt;/title&gt; to the source, the Player settings look like this:

标签名称旁边的文本框包含在构建期间将替换成的自定义标签的文本。

示例

为了说明模板标签的用途,下面提供了 Unity 用于其最小 WebGL 模板的 HTML 源代码。

<!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 | %UNITY_WEB_NAME%</title>
    <script src="%UNITY_WEBGL_LOADER_URL%"></script>
    <script>
    var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%");
    </script>
  </head>
  
  <body>
    <div id="unityContainer" style="width: %UNITY_WIDTH%px; height: %UNITY_HEIGHT%px; margin: auto"></div>
  </body>
  
</html>

最小模板和默认模板都可以在 Unity 安装文件夹中找到:Windows 上的 Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates 下,或者 Mac 上的 /PlaybackEngines/WebGLSupport/BuildTools/WebGLTemplates 下。

添加进度条

Unity WebGL 内容将在加载时自动呈现默认进度条。您可以通过提供自己的进度函数作为附加的实例化参数来覆盖默认的加载进度条。例如:

var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%", {onProgress: UnityProgress});

where UnityProgress is a function of 2 arguments: unityInstance (identifies the unity instance the progressbar belongs to) and progress (a value from 0.0 to 1.0, providing information about the current loading progress).

例如,默认 WebGL 模板中的进度函数看起来如下所示:

var unityInstance = UnityLoader.instantiate("unityContainer", "%UNITY_WEBGL_BUILD_URL%", {onProgress: UnityProgress});

例如,默认 WebGL 模板中的进度函数看起来如下所示:

function UnityProgress(unityInstance, progress) {
  if (!unityInstance.Module)
    return;
  if (!unityInstance.logo) {
    unityInstance.logo = document.createElement("div");
    unityInstance.logo.className = "logo " + unityInstance.Module.splashScreenStyle;
    unityInstance.container.appendChild(unityInstance.logo);
  }
  if (!unityInstance.progress) {    
    unityInstance.progress = document.createElement("div");
    unityInstance.progress.className = "progress " + unityInstance.Module.splashScreenStyle;
    unityInstance.progress.empty = document.createElement("div");
    unityInstance.progress.empty.className = "empty";
    unityInstance.progress.appendChild(unityInstance.progress.empty);
    unityInstance.progress.full = document.createElement("div");
    unityInstance.progress.full.className = "full";
    unityInstance.progress.appendChild(unityInstance.progress.full);
    unityInstance.container.appendChild(unityInstance.progress);
  }
  unityInstance.progress.full.style.width = (100 * progress) + "%";
  unityInstance.progress.empty.style.width = (100 * (1 - progress)) + "%";
  if (progress == 1)
    unityInstance.logo.style.display = unityInstance.progress.style.display = "none";
}

可直接按原样使用,也可将其用作自己模板的参考。由于进度条完全在 JavaScript 中实现,因此可对其进行自定义或替换以显示所需的任何进度指示方式。


  • 2018–10–18 Page amended with no editorial review

  • 5.6 版更新

  • WebGL instance renamed from gameInstance to unityInstance in 2019.1 NewIn20191

WebGL:与浏览器脚本交互
WebGL 中的光标锁定和全屏模式