Version: 2020.1
WebGL Player 设置
WebGL:压缩构建和服务器配置

构建和运行 WebGL 项目

Build 文件夹包含以下文件([ExampleBuild] 表示目标构建文件夹的名称):

文件名 包含
[ExampleBuild].loader.js 网页需要用来加载 Unity 内容的 JavaScript 代码。
[ExampleBuild].framework.js JavaScript 运行时和插件。
[ExampleBuild].wasm WebAssembly 二进制文件。
[ExampleBuild].mem 用于初始化播放器堆内存的二进制映像文件。Unity 仅针对多线程 WebAssembly 构建生成此文件。
[ExampleBuild].data 资源数据和场景。
[ExampleBuild].symbols.json 调试错误堆栈跟踪所需的调试符号名称。仅当启用 Debug Symbols 选项时 (File > Build Settings > Player Settings),才会为 Release 构建生成此文件。
[ExampleBuild].jpg 在构建加载时显示的背景图像。仅当在 Player Settings (File > Build Settings > Player Settings > Splash Image) 中提供了背景图像时,才会生成此文件。有关更多信息,请参阅启动画面页面。

如果对构建启用某种压缩方法,Unity 会识别与压缩方法对应的扩展名,并将此扩展名添加到 Build 子文件夹中的文件的名称中。如果启用 Decompression Fallback,Unity 将扩展名 .unityweb 附加到构建文件名。否则,Unity 为 Gzip 压缩方法附加扩展名 .gz,或者为 Brotli 压缩方法附加扩展名 .br。 有关更多信息,请参阅 WebGL:压缩构建和服务器配置

如果启用 Name Files As Hashes(在 Player Settings 中),Unity 使用文件内容的哈希值而不是默认文件名。这适用于构建文件夹中的每个文件。如果选择此选项,可以将游戏构建的更新版本上传到服务器上的同一文件夹中,并且仅上传在版本迭代之间发生更改的文件。

在本地查看 WebGL Player 的最佳方式是使用 Unity 的 Build And Run 选项(菜单:File > Build And Run)。Unity 使用本地 Web 服务器来托管您的构建,并从本地主机 URL 打开它。或者,可以使用正确配置了响应标头的自定义本地 Web 服务器。有关设置响应标头的更多信息,请参阅 WebGL:压缩构建和服务器配置

注意:在某些浏览器中可能无法直接从文件系统打开播放器。这是由于本地文件 URL 应用了安全限制。

Build Settings

要访问 WebGL 构建设置,请打开 Build Settings 窗口 (File > Build Settings)。然后,从 Platform 列表中选择 WebGL

Build Settings 窗口
Build Settings 窗口

Development Build

选择 Development Build 设置时,Unity 会生成一个支持性能分析器的开发版和一个可供您查看应用程序中任何错误的开发控制台。此外,开发版不会缩减内容。开发版中的 JavaScript 是人类可读格式,而且 Unity 将保留函数名称,以便您可以查看错误的堆栈跟踪。但是,这意味着开发版将非常大,导致无法分发。 仅当启用了 Development Build 设置时,才能选择 Autoconnect ProfilerDeep Profiling Support

Autoconnect Profiler

启用 Autoconnect Profiler 设置可分析 Unity WebGL 内容的性能。对于 WebGL,无法像在其他平台上那样将性能分析器连接到正在运行的构建,因此必须使用此选项将内容连接到 Editor。这是因为性能分析器连接是使用 WebGL 上的 WebSockets 处理的,但 Web 浏览器仅允许来自内容的传出连接。

Deep Profiling Support

启用 Deep Profiling Support 设置可使 Unity Profiler 对应用程序中的每次函数调用都进行性能分析。如需了解更多信息,请参阅有关深度性能分析的文档。

播放器设置 (Player settings)

WebGL 在 Player 设置(菜单:Edit > Project Settings,然后选择 Player 类别)中有一些其他选项。

Other Settings

Strip Engine Code

打开 Other Settings 访问 Strip Engine Code 选项。默认情况下会选中此选项以启用 WebGL 的代码剥离。选中此选项后,Unity 不会包含未使用的任何类的代码。例如,如果不使用任何物理组件或函数,则会从构建中删除整个物理引擎。有关更多详细信息,请参阅下面的“剥离”部分。

Publishing Settings

Enable Exceptions

打开 Publishing Settings 访问 Enable ExceptionsEnable Exceptions 允许指定在运行时如何处理意外的代码行为(通常视为错误)。该设置具有以下选项:

  • None:如果不需要任何异常支持,请选择此选项。此选项可提供最佳性能和最小构建。使用此选项,抛出的任何异常都会导致内容因该设置中的错误而停止。
  • Explicitly Thrown Exceptions Only(默认设置):选择此选项可捕获从脚本中的 throw 语句显式指定的异常,并可确保调用 finally 代码块。请注意,选择此选项会使脚本中生成的 JavaScript 代码变得更长且更慢;仅当脚本是项目的主要瓶颈时,这才会成为问题。
  • Full Without Stacktrace:选择此选项可捕获:
    • 从脚本中的 throw 语句显式指定的异常(与 Explicitly Thrown Exceptions Only 选项一样)
    • Null 引用
    • 越界数组访问
  • Full With Stacktrace:此选项与上面的选项类似,但也捕获堆栈跟踪。Unity 通过在代码中嵌入对异常检查来生成这些异常,因此该选项会降低性能并增加浏览器内存使用量。仅用于调试,并始终在 64 位浏览器中进行测试。

选择 Publishing Settings 以访问数据缓存

数据缓存

要访问数据缓存,请选择 Publishing Settings (File > Build Settings > Player Settings > WebGL > Publishing Settings)。这样,浏览器会将主数据文件缓存到 IndexedDB 数据库中。

使用默认浏览器 HTTP 缓存并不能保证浏览器缓存特定响应。这是因为浏览器 HTTP 缓存空间有限,浏览器可能无法缓存过大的文件。

为了提高加载速度,IndexedDB 允许您缓存超过浏览器限制的文件。缓存更多文件时,下一次构建运行期间下载内容在用户计算机上可用的机会就增加了。

数据缓存仅为 HTTP 响应缓存 IndexedDB 缓存中的 .data 文件。要缓存资源包,需要启用数据缓存并覆盖 unityInstance.Module.cacheControl()。 为此,请确保 Module.cacheControl(url) 为请求的资源包 URL 返回 must-revalidate。例如,您可以在 createUnityInstance() 返回的 Promise 的执行回调中重写 unityInstance.Module.cacheControl() 函数。 有关 createUnityInstance() 的更多信息,请参阅 WebGL:压缩构建和服务器配置

以 WebGL 为目标进行发布时,必须保持较低的构建大小,让用户在内容启动之前等待合理的下载时间,这一点很重要。有关减小资源大小的一般提示,请参阅减小构建文件大小相关文档。

分发大小

以 WebGL 为目标进行发布时,必须保持较低的构建大小,让用户在内容启动之前等待合理的下载时间,这一点很重要。有关减小资源大小的一般提示,请参阅减小构建文件大小相关文档。

WebGL 特有的提示和技巧

  • 纹理导入器 (Texture Importer) 中为所有压缩纹理指定 Crunch 纹理压缩格式。

  • 不要部署开发版本;它们不会经过压缩或缩小,因此文件大小要大得多。

  • 打开 Player 设置(菜单:Edit > Project Settings,然后选择 Player 类别),打开 Publishing Settings 面板,并将 Enable Exceptions 设置为 None(如果在构建中不需要异常)。

  • 打开 Player 设置(菜单:Edit > Project Settings,然后选择 Player 类别),打开 Other Settings 面板,然后启用 Strip Engine Code 以确保进行高效构建。

  • 使用第三方托管的 dll 时要小心,因为它们可能包含大量依赖项,所以会显著增加生成的代码大小。

如果要构建发布版本,Unity 将根据在 WebGL Player 设置的 Publishing Settings 面板中选择的 Compression Format 来压缩构建输出文件。

有关这些选项的更多信息以及如何使用它们发布构建,请参阅有关部署压缩构建的文档。

AssetBundle

由于所有资源数据都需要在内容启动之前预先下载,因此应考虑将资源从主数据文件中移出到 AssetBundle中。这样,就能为内容创建一个小型加载场景,确保快速加载。然后,当用户继续浏览内容时,将按需动态加载资源。AssetBundle 还有助于进行资源数据内存管理:可通过调用 AssetBundle.Unload 从内存中卸载掉不再需要的资源的资源数据。

在 WebGL 平台上使用 AssetBundle 时的注意事项:

  • 在 AssetBundle 中使用未在主构建中使用的类类型时,Unity 可能会从构建中剥离这些类的代码。尝试从 AssetBundle 加载资源时,这可能会导致失败。请使用 BuildPlayerOptions.assetBundleManifestPath 修复该问题,或参阅下面有关剥离的部分以了解其他选项。

  • WebGL 不支持线程,但 http 下载内容仅在下载完成后才可用。因此,在下载完成时,Unity WebGL 构建需要在主线程上解压缩 AssetBundle 数据,而这会阻止主线程。为避免这种中断,LZMA AssetBundle 压缩不可用于 WebGL 上的 AssetBundle。此情况下使用 LZ4 对 AssetBundle 进行压缩,这种压缩格式可非常高效地按需进行解压缩。如果所需的压缩大小比 LZ4 能够提供的压缩大小更小,可将 Web 服务器配置为对 AssetBundle 使用 gzip 或 Brotli 压缩(基于 LZ4 压缩)。请参阅有关部署压缩构建的文档以详细了解如何执行此操作。

  • WebGL 支持通过 WWW.LoadFromCacheOrDownload 对 AssetBundle 进行缓存,可使用来自浏览器的 IndexedDB API 在用户的计算机上实现缓存。请注意,IndexedDB 可能对某些浏览器提供的支持有限,并且浏览器可能会请求用户授权将数据存储在磁盘上。请参阅有关 WebGL 浏览器兼容性的文档以了解更多信息。

剥离

默认情况下,Unity 会从构建中删除所有未使用的代码。可通过 Player 设置(菜单:Edit > Project Settings,然后选择 Player 类别)来更改此设置:选择 Other Settings 面板访问 Strip Engine Code 选项。最好在启用剥离的情况下进行构建。

启用代码剥离后,Unity 扫描会项目以查找是否使用了 UnityObject 派生的任何类(通过在脚本代码中或在场景中的序列化数据中引用)。然后从构建中删除所有未使用这些类的 Unity 子系统。这样可减少构建代码,从而减小下载和要解析的代码(因此代码运行速度更快,且占用的内存更少)。

代码剥离的问题

如果代码剥离时剥离了实际需要的代码,可能会导致项目出现问题。例如,如果在运行时加载的 AssetBundle 所包含的类未包括在主构建中,因此从项目中删除了这些 AssetBundle,这种情况下就可能出问题。发生这种情况时,浏览器的 JavaScript 控制台中会显示错误消息(随后可能会显示更多错误)。例如:

Could not produce class with ID XXX

要解决这些错误,请在类 ID 参考中查找该 ID(如上例中的 XXX),看哪个类在尝试创建实例。在这种情况下,可强制 Unity 在构建中包含该类的代码,方法是向脚本或向场景添加对该类的引用,或者在项目中添加 link.xml 文件。

下面的示例确保了 Collider 类(因此也包括 Physics 模块)在项目中得到保留。可将此 XML 代码添加到名为 link.xml 的文件,然后将该文件放入 Assets 文件夹。

<linker>
    <assembly fullname="UnityEngine">
        <type fullname="UnityEngine.Collider" preserve="all"/>
    </assembly>
</linker>

如果怀疑剥离导致构建出现问题,还可尝试在测试期间禁用 Strip Engine Code 选项。

通过查看构建中包含哪些模块和类可以优化项目的剥离功能,但 Unity 未提供方便的方法来进行此操作。不过,若要了解包含的类和模块的概况,可在进行构建之后查看生成的文件 Temp/StagingArea/Data/il2cppOutput/UnityClassRegistration.cpp

请注意,Strip Engine Code 选项仅影响 Unity 引擎代码。IL2CPP 始终会从托管的 dll 和脚本中剥离字节代码。需要通过反射(而不是通过代码中的静态引用)来动态引用托管的类型时,这可能会导致问题。如果需要通过反射来访问类型,可能还需要设置 link.xml 文件才能保留这些类型。请参阅有关 iOS 构建大小优化的文档页面以了解关于 link.xml 文件的更多信息。

移动构建输出文件

要更改 Build 文件夹的位置,请修改 WebGL 模板 index.html 文件中的 buildUrl 变量。

要更改 Build 文件夹内的文件的位置,请在 index.html 文件中更改它们的 URL(即 dataUrlwasmCodeUrlwasmMemoryUrlwasmFrameworkUrl)。

如果要在内容分发网络 (CDN) 上托管文件,可指定位于外部服务器上的 URL,但需要确保托管服务器已启用跨源资源共享 (CORS) 才能保证正常工作。有关 CORS 的更多信息,请参阅手册中的 WebGL 网络页面。

增量构建

IL2CPP 为项目生成的 C++ 代码采用增量编译方式;也就是说,只有自上次构建以来生成的已更改的 C++ 代码才会再次编译。未更改的源代码将重复使用先前构建所生成的相同目标文件。用于增量式 C++ 构建的目标文件存储在 Unity 项目的 Library/il2cpp_cache 目录中。

要对生成的 C++ 代码执行从头开始的全新构建而不使用增量编译,请删除 Unity 项目中的 Library/il2cpp_cache 目录。请注意,如果 Unity 编辑器版本与以前的 WebGL 构建版本不同,Unity 会自动从头开始执行全新的构建。


  • 在 Unity 2017.3 中添加了 Full Without Stacktrace
  • 在 Unity 2019.1 中删除了 asm.js 链接器目标
  • Unity 2020.1 中添加了构建文件更新和数据缓存
WebGL Player 设置
WebGL:压缩构建和服务器配置