Version: 2023.1
Distribution size and code stripping
Deploy WebGL application

WebGL templates

Important: To use the templates feature in WebGL, you need prior knowledge of JavaScript concepts and terminology.

When you build a WebGL project, Unity embeds the Player in a HTML page such that a browser can open it. A WebGL template is a configuration setting that lets you control the appearance of this HTML page, so that you can: test, demonstrate, and preview your WebGL application in a browser.

To access WebGL templates:

  1. Go to Player settings (menu: Edit > Project Settings > Player), and set the platform-specific settings to WebGL.
  2. Open Resolution and Presentation.
播放器 Resolution and Presentation 窗口的图像。
播放器 Resolution and Presentation 窗口的图像。

By default, the WebGL Template setting has the following options:

  • Default: A white page with a loading bar on a grey canvas.
  • Minimal: A minimal WebGL template with that includes the necessary boilerplate code to run the WebGL content.
  • PWA: A Progressive Web App including a web manifest file and service worker code.

这些内置 HTML 页面对于测试和演示最小播放器非常有用。

You can also use JavaScript to build and supply your own WebGL templates to host the Player. This is useful for production purposes, so that you can preview the Player hosted in the page where it’s eventually deployed. For example, if the Unity Player content interacts with other elements in the page via the external call interface, you should test it with a page that contains those interacting elements.

添加 WebGL 模板

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

The easiest way to create a new custom WebGL template is to make a copy of the built-in Default or Minimal templates, which are stored in corresponding subfolders under <Unity Installation>/PlaybackEngines/WebGLSupport/BuildTools/WebGLTemplates/. Every Unity Project includes these templates by default. Copy a template and place it in your own Project/Assets/WebGLTemplates folder, and rename it to something meaningful so you can identify your template later.

Note: On Mac, you can locate the Unity Installation folder in the Applications folder.

Templates in your Project’s WebGLTemplates folder appear in the Unity Player Settings’ WebGL Template setting. The name of the template is the same as its folder. To give this option a thumbnail image for easy reference, add a 128x128-pixel image to the template folder and name it thumbnail.png.

模板变量、宏和条件指令

在构建过程中,Unity 会预处理模板文件并计算这些文件中包含的所有宏和条件指令。作为此过程的一部分,Unity 会查找所有宏声明并将其替换为编辑器提供的值。Unity 会自动预处理模板文件夹中的所有 .html、.php、.css、.js 和 .json 文件。

内部预处理器变量

以下内部预处理器变量引用项目中的数据,Unity 在构建时会根据编辑器提供的值向它们分配值。Javascript 宏和条件指令可以使用这些内部预处理器变量。

可变 类型 描述
COMPANY_NAME String 在 Player Settings 中定义的 Company Name。
PRODUCT_NAME String 在 Player Settings 中定义的 Product Name。
PRODUCT_VERSION String 在 Player Settings 中定义的 Version。
WIDTH Integer 在 Player Settings > Resolution and Presentation 中定义的 Default Canvas Width。
HEIGHT Integer Player Settings > Resolution and Presentation 中的 Default Canvas Height。
SPLASH_SCREEN_STYLE String This’s set to the “Dark” value when Splash Style Player Settings > Splash Image is set to Light on Dark, otherwise it’s set to the “Light” value.
BACKGROUND_COLOR String 表示以十六进制三元组形式定义的背景颜色。
UNITY_VERSION String Unity 版本。
DEVELOPMENT_PLAYER Boolean This’s set to true if the Development Build option is enabled.
DECOMPRESSION_FALLBACK String This’s set to Gzip or Brotli, depending on the compression method you use and the type of decompressor included in the build. If neither is included, the variable is set to an empty string.
INITIAL_MEMORY Integer The initial size of the WASM memory heap in megabytes (MB).
USE_WASM Boolean 如果当前构建是 WebAssembly 构建,则此变量设置为 true。
USE_THREADS Boolean 如果当前构建使用线程,则此变量设置为 true。
USE_WEBGL_1_0 Boolean 如果当前构建支持 WebGL1.0 图形 API,则此变量设置为 true。
USE_WEBGL_2_0 Boolean 如果当前构建支持 WebGL2.0 图形 API,则此变量设置为 true。
USE_DATA_CACHING Boolean 如果当前构建对下载的文件使用 indexedDB 缓存,则此变量设置为 true。
LOADER_FILENAME String 此变量设置为构建加载程序脚本的文件名。
DATA_FILENAME String 此变量设置为主数据文件的文件名。
FRAMEWORK_FILENAME String 此变量设置为构建框架脚本的文件名。
CODE_FILENAME String This is set to the filename of the WebAssembly module when the current build is a WebAssembly build, otherwise it’s set to the filename of the asm.js module.
MEMORY_FILENAME String This is set to the filename of the memory file when memory is stored in an external file, otherwise it’s set to an empty string.
SYMBOLS_FILENAME String This is set to the filename of the JSON file containing debug symbols when the current build is using debug symbols, otherwise it’s set to an empty string.
BACKGROUND_FILENAME String This is set to the filename of the background image when the background image is selected in the Player Settings > Splash Image, otherwise it’s set to an empty string.

JavaScript 宏

JavaScript 宏是模板文件中的 JavaScript 代码块,由三组花括号括起。此 JavaScript 代码可以使用上面列出的内部预处理器变量。这些变量在构建时根据编辑器提供的值进行分配。在构建期间,预处理器会计算所有宏并将它们替换为变量的输出。

可以使用 JavaScript 宏预处理编辑器提供的值。这些宏可以实现任意您所需的复杂性。它们可以包含多个运算符、循环、函数和任何其他 JavaScript 结构。

以下示例行来自 Default 模板中使用的 index.html 文件:

<div id="unity-build-title">{{{ PRODUCT_NAME }}}</div>

If the value of the Product Name in the Player Settings is set to My WebGL Game, the internal preprocessor variable PRODUCT_NAME has the value My WebGL Game. In the output index.html file, the line appears as:

<div id="unity-build-title">My WebGL Game</div>

下面是来自同一 index.html 模板文件的更复杂示例:

canvas.style.background = "url('" + buildUrl + "/{{{ BACKGROUND_FILENAME.replace(/'/g, '%27') }}}') center / cover";

If the target build folder is called Let’s try WebGL, and if you select a background image in the Player Settings, the internal preprocessor variable BACKGROUND_FILENAME has the value Let’s try WebGL.jpg. In the output index.html file, the line changes into:

canvas.style.background = "url('" + buildUrl + "/Let%27s try WebGL.jpg') center / cover";

条件指令

条件指令 #if#else#endif 控制 Unity 是在输出文件中包含预处理文件的特定部分,还是在当前构建中丢弃它。

Code that starts with an #if directive and ends with an #endif directive is called a conditional group. Conditional groups can also include #else directives. Unity evaluates the expression written after the #if as a JavaScript expression. If this expression has a truthy value that translates to true when evaluated in a Boolean context, then Unity keeps the line group immediately following the #if directive in the output file. If the #if expression is false, and an #else directive is included in the conditional group, Unity keeps the line group immediately following the #else directive in the output. An example of a conditional group is as follows:

# if EXPRESSION
  // 如果 EXPRESSION 具有真值,则此代码块包含在输出中
# else
  // 否则此代码块包含在输出中
# endif

计算的 JavaScript 表达式可以包含括号、逻辑运算符和其他 JavaScript 结构。条件指令可以嵌套。

自定义用户变量

When you select a WebGL template, Unity parses the template and looks for Javascript macros and conditional directives. JavaScript variables are treated as custom user variables if they’re:

  • Used inside JavaScript macros and conditional directives.
  • Not declared in the template code.
  • Not internal pre-processor variables.

Unity 自动将这些自定义用户变量添加到 Player Settings 窗口中的 Resolution and Presentation 部分。

例如,如果要直接从 Player Settings 窗口控制生成的 index.html 页面的标题,则首先需要在自定义模板中修改 index.html&lt;title&gt; 行,如下所示: <title>{{{ PAGE_TITLE }}}</title> 完成此操作后,重新选择自定义模板。这会再次解析模板,您应该会在 Player Settings windowResolution and Presentation > WebGL Template 部分中找到 Page Title 字段。

带有自定义模板的 Resolution and Presentation 窗口图像
带有自定义模板的 Resolution and Presentation 窗口图像

在此字段中输入文本并构建项目时,模板宏中使用的自定义变量 PAGE_TITLE 会自动成为 Page Title 字段中的文本。

如果要在宏中使用自定义整数或浮点变量,请在宏中使用 parseInt()parseFloat() JavaScript 函数以预处理编辑器提供的字符串值。这是因为会始终向自定义用户变量分配字符串值。

注意:变量名称中的下划线字符在字段内会显示为空格以提高可读性。

index.html 文件的结构

index.html 包含加载构建所需的代码,应包含以下内容:

  • 一个 <canvas> 元素。Unity 运行时使用 <canvas> 元素渲染应用程序。
  • 用于下载构建加载程序的 JavaScript 代码。例如:
var buildUrl = "Build";
var loaderUrl = buildUrl + "/{{{ LOADER_FILENAME }}}";
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
  // 用于实例化构建的代码
};
document.body.appendChild(script);`

在此示例中,{{{ LOADER_FILENAME }}} 在生成构建时由模板预处理器自动解析。

或者,可以使用脚本标签下载构建加载程序,例如: lang-js <script src="Build/{{{ LOADER_FILENAME }}}"></script>

  • 用于实例化构建的 JavaScript 代码。Unity 构建使用 createUnityInstance() 函数进行实例化,该函数在构建加载程序脚本中定义。

实例化函数:createUnityInstance()

createUnityInstance() 函数为您的内容创建新实例。可以按如下所示使用它: createUnityInstance(canvas, config, onProgress).then(onSuccess).catch(onError);

此函数返回一个 Promise 对象,其中:

对象 用途
canvas Unity 运行时使用 canvas 对象渲染游戏。
config config 对象包含构建配置,例如代码和数据 URL、产品和公司名称以及版本。有关配置定义的更多信息,请参阅本页面上的构建配置部分。
onProgress(progress) {...} 每次下载进度更新时,WebGL 加载程序都会调用 onProgress 回调对象。onProgress 回调附带的 progress 参数会确定加载进度(形式为介于 0.0 与 1.0 之间的值)。
onSuccess(unityInstance) {...} 构建成功实例化之后会调用 onSuccess 回调。创建的 Unity 实例对象作为参数提供。此对象可以用于与构建交互。
onError(message) {...} 如果在构建实例化期间发生错误,则调用 onError 回调。错误消息作为参数提供。

createUnityInstance() 函数在构建加载程序脚本中定义,特定于实例化的构建。因此,如果在同一个 HTML 文档中嵌入两个或更多构建,请确保从相应构建加载程序脚本的 onload 回调中调用 createUnityInstance() 函数。有关 Unity WebGL 加载程序的更多信息,请参阅构建和运行 WebGL 项目

构建配置

配对对象包含构建配置,而构建配置由代码和数据 URL、产品名称、公司名称和版本组成。可以使用以下代码定义它:

var buildUrl = "Build";
var config = {
  dataUrl: buildUrl + "/{{{ DATA_FILENAME }}}",
  frameworkUrl: buildUrl + "/{{{ FRAMEWORK_FILENAME }}}",
  codeUrl: buildUrl + "/{{{ CODE_FILENAME }}}",
# if MEMORY_FILENAME
  memoryUrl: buildUrl + "/{{{ MEMORY_FILENAME }}}",
# endif
# if SYMBOLS_FILENAME
  symbolsUrl: buildUrl + "/{{{ SYMBOLS_FILENAME }}}",
# endif
  streamingAssetsUrl: "StreamingAssets",
  companyName: "{{{ COMPANY_NAME }}}",
  productName: "{{{ PRODUCT_NAME }}}",
  productVersion: "{{{ PRODUCT_VERSION }}}",
};

在上面的示例中,构建文件夹 URL 存储为名为 buildUrl 的单独变量。在不知道嵌入页面与托管服务器上的构建文件夹之间关系的情况下,这十分有用。它使您能够在其他 HTML 文档中重用嵌入代码。何时使用此方法的一个示例是将 Build 文件夹移动到服务器上的另一个位置的情况。可以在嵌入页面中调整 buildUrl 变量的值,并且可以使用相同的嵌入代码。这也适用于 StreamingAssets 文件夹 (streamingAssetsUrl)。

构建交互

构建成功实例化后,Promise 对象的执行处理程序回调会接收新创建的 Unity 实例对象(以参数形式)。要与构建交互,请调用 Unity 实例的以下方法:

方法 用途
unityInstance.SetFullscreen(fullscreen) The SetFullscreen method toggles full screen mode. This method doesn’t return a value.
- Full screen mode is activated when the fullscreen argument has a value of 1.
- Full screen mode is disabled when the fullscreen argument has a value of 0.
unityInstance.SendMessage(objectName, methodName, value) The SendMessage method sends messages to the GameObjects. This method doesn’t return a value.
- objectName is the name of an object in your Scene.
- methodName is the name of a method in the script, currently attached to that object.
- value can be a string, a number, or it can be empty.
unityInstance.Quit().then(onQuit) Use the Quit() method to quit the runtime and clean up the memory used by the Unity instance. This method returns a Promise object.
- onQuit callback is called after the build runtime has quit.
Distribution size and code stripping
Deploy WebGL application