本页面需要 JavaScript 概念和术语方面的预备知识。
构建 WebGL 项目时,Unity 会将播放器嵌入到 HTML 页面中,以便浏览器可以打开它。WebGL 模板是一种配置设置,使您可以控制此 HTML 页面的外观,以便您可以在 HTML 页面中测试、演示和预览 WebGL 应用程序。 要访问 WebGL 模板,请转到Player settings(菜单:Edit > Project Settings > Player),将特定于平台的设置设置为 WebGL,然后打开 Resolution and Presentation。
默认情况下,WebGL 模板设置具有两个选项:
这些内置 HTML 页面对于测试和演示最小播放器非常有用。
还可以使用 JavaScript 构建和提供自己的 WebGL 模板以托管播放器。这对于生产用途非常有用,使您可以预览在最终部署的页面中托管的播放器。例如,如果 Unity 播放器内容通过外部调用接口与页面中的其他元素交互,则应使用包含这些交互元素的页面进行测试。
要将自定义模板添加到项目,请导航到项目的 Assets
文件夹并创建一个名为 WebGLTemplates
的文件夹。每个模板都是 WebGLTemplates
文件夹中的子文件夹。每个模板子文件夹都包含一个 index.html
文件以及页面所需的任何其他资源,例如图像或样式表。
创建新的自定义 WebGL 模板的最简单方法是复制内置 Default 或 Minimal 模板。这些模板存储在 <Unity Installation>/PlaybackEngines/WebGLSupport/BuildTools/WebGLTemplates/
下的相应子文件夹中。默认情况下,每个 Unity 项目都包含这些模板。复制一个模板并将它放在您自己的 Project/Assets/WebGLTemplates
文件夹中,并将它重命名为有意义的内容,以便您以后可以识别您的模板。
项目的 WebGLTemplates
文件夹中的模板会出现在 Unity Player Settings 的 WebGL Template 设置中。模板的名称与其文件夹相同。要为此选项提供缩略图以便于参考,请将 128x128 像素的图像添加到模板文件夹并将它命名为 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 | 当 Splash Style Player Settings > Splash Image 设置为 Light on Dark 时,此变量设置为“Dark”值,否则设置为“Light”值。 |
BACKGROUND_COLOR | String | 表示以十六进制三元组形式定义的背景颜色。 |
UNITY_VERSION | String | Unity 版本。 |
DEVELOPMENT_PLAYER | Boolean | 如果启用了 Development Build 选项,则此变量设置为 true。 |
DECOMPRESSION_FALLBACK | String | 此变量设置为“Gzip”或“Brotli”,具体取决于使用的压缩方法以及构建中包含的解压缩程序。如果两者都不包含,则变量设置为空字符串。 |
TOTAL_MEMORY | Integer | 内存堆的初始大小(以字节为单位)。 |
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 | 在当前构建是 WebAssembly 构建时,此变量设置为 WebAssembly 模块的文件名,否则设置为 asm.js 模块的文件名。 |
MEMORY_FILENAME | String | 当内存存储在外部文件中时,此变量设置为内存文件的文件名,否则设置为空字符串。 |
SYMBOLS_FILENAME | String | 在当前构建使用调试符号时,此变量设置为包含调试符号的 JSON 文件的文件名,否则设置为空字符串。 |
BACKGROUND_FILENAME | String | 当在 Player Settings > Splash Image 中选择了背景图像时,此变量设置为背景图像的文件名,否则设置为空字符串。 |
JavaScript 宏是模板文件中的 JavaScript 代码块,由三组花括号括起。此 JavaScript 代码可以使用上面列出的内部预处理器变量。这些变量在构建时根据编辑器提供的值进行分配。在构建期间,预处理器会计算所有宏并将它们替换为变量的输出。
可以使用 JavaScript 宏预处理编辑器提供的值。这些宏可以实现任意您所需的复杂性。它们可以包含多个运算符、循环、函数和任何其他 JavaScript 结构。
以下示例行来自 Default 模板中使用的 index.html
文件:
<div id="unity-build-title">{{{ PRODUCT_NAME }}}</div>
如果 Player Settings 中 Product Name 的值设置为“My WebGL Game”,则内部预处理器变量 PRODUCT_NAME 具有值“My WebGL Game”。在输出 index.html
文件中,该行显示为:
<div id="unity-build-title">My WebGL Game</div>
下面是来自同一 index.html
模板文件的更复杂示例:
canvas.style.background = "url('" + buildUrl + "/{{{ BACKGROUND_FILENAME.replace(/'/g, '%27') }}}') center / cover";
如果目标构建文件夹名为 Let’s try WebGL
,并且在 Player Settings 中选择了背景图像,则内部预处理器变量 BACKGROUND_FILENAME 具有值“Let’s try WebGL.jpg”。在输出 index.html
文件中,该行更改为:
canvas.style.background = "url('" + buildUrl + "/Let%27s try WebGL.jpg') center / cover";
条件指令 #if、#else 和 #endif 控制 Unity 是在输出文件中包含预处理文件的特定部分,还是在当前构建中丢弃它。
以 #if 指令开头并以 #endif 指令结尾的代码称为条件组。条件组还可以包含 #else 指令。Unity 会计算在 #if 后编写为 JavaScript 表达式的表达式。如果此表达式具有真值(即,在布尔值上下文中计算时转换为 true 的值),Unity 会在输出文件中保留紧跟在 #if 指令后的行组。如果 #if 表达式为 false,并且条件组中包含 #else 指令,则 Unity 会在输出中保留紧跟在 #else 指令后的行组。 条件组的示例如下所示:
# if EXPRESSION
// 如果 EXPRESSION 具有真值,则此代码块包含在输出中
# else
// 否则此代码块包含在输出中
# endif
计算的 JavaScript 表达式可以包含括号、逻辑运算符和其他 JavaScript 结构。条件指令可以嵌套。
选择 WebGL 模板时,Unity 会解析模板并查找 Javascript 宏和条件指令。 如果 JavaScript 变量满足以下所有条件,则它们会被视为自定义用户变量:
Unity 自动将这些自定义用户变量添加到 Player Settings 窗口中的 Resolution and Presentation 部分。
例如,如果要直接从 Player Settings 窗口控制生成的 index.html
页面的标题,则首先需要在自定义模板中修改 index.html
的 <title>
行,如下所示:
<title>{{{ PAGE_TITLE }}}</title>
完成此操作后,重新选择自定义模板。这会再次解析模板,您应该会在 Player Settings window 的 Resolution and Presentation > WebGL Template 部分中找到 Page Title 字段。
在此字段中输入文本并构建项目时,模板宏中使用的自定义变量 PAGE_TITLE 会自动成为 Page Title 字段中的文本。
如果要在宏中使用自定义整数或浮点变量,请在宏中使用 parseInt()
或 parseFloat()
JavaScript 函数以预处理编辑器提供的字符串值。这是因为会始终向自定义用户变量分配字符串值。
注意:变量名称中的下划线字符在字段内会显示为空格以提高可读性。
index.html
包含加载构建所需的代码,应包含以下内容:
<canvas>
元素。Unity 运行时使用 <canvas>
元素渲染应用程序。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>
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) |
SetFullscreen 方法切换全屏模式。此方法不返回值。- 当 fullscreen 参数的值为 1 时,全屏模式会激活。*当 fullscreen 参数的值为 0 时,全屏模式会禁用。 |
unityInstance.SendMessage(objectName, methodName, value) |
SendMessage 方法向游戏对象发送消息。此方法不返回值。 - objectName 是场景中对象的名称。 - methodName 是脚本中方法的名称,当前附加到该对象。 - value 可以是字符串、数字,也可以为空。 |
unityInstance.Quit().then(onQuit) |
Quit() 方法可用于退出运行时并清理 Unity 实例使用的内存。此方法返回 Promise 对象。- 在构建运行时退出后会调用 onQuit 回调。 |