部署压缩工程
当你在发布模式下构建WebGL项目时,Unity会将你工程的输出文件进行压缩,以降低工程下载的份量。你可以在发布设置中的压缩格式选项里,选择压缩的类型(菜单:Edit->Project Settings -> Player -> Publishing Settings):
- gzip:这是默认选项。gzip文件比Brotli文件更大,但构建速度更快,并且被所有浏览器在http协议和https协议都原生支持。文件名会有.gzip的额外后缀。
- Brotli:Brotli压缩提供了最棒的压缩率。Brotli压缩文件明显比gzip文件小,但会花很长时间来压缩,增加了你发布版工程的迭代时间。Brotli押送被Chrome和Firefox在https协议中原生支持(查看WebGL浏览器兼容性来获得更多信息)。Brotli压缩文件会有.br后缀。
- Disabled:这禁用了压缩功能。如果你希望在预处理脚本中实现你自己的压缩,使用这个选项。
压缩构建的Unity工程可以在任何浏览器上工作。Unity 包含了一个用JavaScript编写的软件解压器,当服务器端不启用http压缩传输时,它会回退。数据被浏览器从服务器上下载,并且被Unity的加载器代码所解压缩。当这些完成时,在你浏览器的JavaScript控制台中出现信息(包含了你的文件名而不是这里的例子):
82毫秒完成解压缩<Example/MyProject.jsgz>。如果你设置网页浏览器使用压缩来管理文件,你可以移除这个延迟。
这里,82毫秒只是个例子;花费的毫秒数量依赖于内容大小,以及计算机的速度。更大的工程花费更长的解压缩时间,更快的计算机消耗更少的时间。将解压缩时间打出,以提示你:你可以通过让浏览器掌控解压缩,来节约多少启动时间。
进阶:浏览器本地解压
浏览器可以在它下载Unity工程的数据时就在本地进行解压。这有避免了因在JavaScript中解压缩文件而产生额外延迟的好处,减少了启动时间。为了让浏览器进行本地解压,需要配置网页服务器用正确的http头提供压缩文件:这告诉浏览器,数据使用gzip或者Brotli方式压缩,从而浏览器在数据开始传输时就解压。Brotli压缩被Firefox和Chrome仅在https协议中支持,而gzip压缩被所有浏览器支持。查看WebGL browser compatibility 来获取更多信息。
设置网页服务器
对浏览器本地解压的设置过程依赖于你的网页服务器。本页的说明适用于两种最主流的网页服务器,Apache和IIS。注意,这些在默认设置下可用,但可能需要调整以匹配你的个性化设置。尤其,如果你已经有了另一个服务器端配置来压缩本地文件时,可能会有妨碍这里设置的问题。
Apache
Apache使用不可见的.htaccess文件进行服务器设置。下方的样例代码展示了一个.htaccess文件的例子,你可以放进你的发行目录来配置Apache,以掌控你的压缩文件。
<IfModule mod_rewrite.c>
<IfModule mod_mime.c>
Options +SymLinksIfOwnerMatch
RewriteEngine on
RewriteCond %{HTTP:Accept-encoding} br
RewriteCond %{REQUEST_FILENAME}br -f
RewriteRule ^(.*)\.(js|data|mem|unity3d)$ $1.$2br [L]
AddEncoding br .jsbr
AddEncoding br .databr
AddEncoding br .membr
AddEncoding br .unity3dbr
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}gz -f
RewriteRule ^(.*)\.(js|data|mem|unity3d)$ $1.$2gz [L]
AddEncoding gzip .jsgz
AddEncoding gzip .datagz
AddEncoding gzip .memgz
AddEncoding gzip .unity3dgz
</IfModule>
</IfModule>
当Apache接收到一个对文件的请求(例如Release/mgame.js),这里的配置检查,客户端是否允许Brotli-编码的数据(RewriteCond %{HTTP:Accept-encoding} br),然后检查在 Release/mygame.jsb**r 是否有文件 (RewriteCond %{REQUEST_FILENAME}br -f)。如果两种情况都匹配,Apach重写请求到.jsbr文件中,并响应。AddEncoding br .jsbr 通知Apache通过添加头部来告诉客户端,文件使用Brotli编码。
随后的样例代码块对gzip做相同设置。因此,如果 Release/mygame.jsgz 文件存在、但Brotli压缩的条件不成立,Apache会用.gzip格式文件处理。
IIS
IIS使用web.config文件进行服务器配置。以下样例代码展示了一个web.config文件的例子,你可以放到你的Release目录中来配置IIS如何处理压缩文件。
为了使用这个,你需要安装Microsoft的IIS URL Rewrite IIS 模块;否则,浏览器会抛出一个500 内部服务器错误。如果你没有安装这个模块,你扔可以使用这个文件,但没有在< rewrite>和< /rewrite>之间的代码。这无法让压缩传输可用,但让IIS可以处理文件扩展。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".mem" />
<remove fileExtension=".data" />
<remove fileExtension=".unity3d" />
<remove fileExtension=".jsbr" />
<remove fileExtension=".membr" />
<remove fileExtension=".databr" />
<remove fileExtension=".unity3dbr" />
<remove fileExtension=".jsgz" />
<remove fileExtension=".memgz" />
<remove fileExtension=".datagz" />
<remove fileExtension=".unity3dgz" />
<mimeMap fileExtension=".mem" mimeType="application/octet-stream" />
<mimeMap fileExtension=".data" mimeType="application/octet-stream" />
<mimeMap fileExtension=".unity3d" mimeType="application/octet-stream" />
<mimeMap fileExtension=".jsbr" mimeType="application/octet-stream" />
<mimeMap fileExtension=".membr" mimeType="application/octet-stream" />
<mimeMap fileExtension=".databr" mimeType="application/octet-stream" />
<mimeMap fileExtension=".unity3dbr" mimeType="application/octet-stream" />
<mimeMap fileExtension=".jsgz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".memgz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".datagz" mimeType="application/octet-stream" />
<mimeMap fileExtension=".unity3dgz" mimeType="application/octet-stream" />
</staticContent>
<rewrite>
<rules>
<rule name="Append br suffix to WebGL content requests">
<match url="(.*)\.(js|data|mem|unity3d)$" />
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
<add input="{REQUEST_FILENAME}br" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}br" />
</rule>
<rule name="Append gz suffix to WebGL content requests">
<match url="(.*)\.(js|data|mem|unity3d)$" />
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}gz" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}gz" />
</rule>
</rules>
<outboundRules>
<rule name="Append br Content-Encoding header to the rewritten responses">
<match serverVariable="RESPONSE_Content-Encoding" pattern=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" pattern="\.(js|data|mem|unity3d)br$" />
</conditions>
<action type="Rewrite" value="br" />
</rule>
<rule name="Append gzip Content-Encoding header to the rewritten responses">
<match serverVariable="RESPONSE_Content-Encoding" pattern=".*" />
<conditions>
<add input="{REQUEST_FILENAME}" pattern="\.(js|data|mem|unity3d)gz$" />
</conditions>
<action type="Rewrite" value="gzip" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
如果这些扩展可以在更高一级的目录结构中被覆盖,你只需要 《remove fileExtension=”.*” 》这一行。
WebGL工程的调试及问题捕获
Unity WebGL内容无法正确地被调试用MonoDevelop或者Visual Studio,这让你很难找出到底是什么东西出错了。这里有些提示关于如何从你的工程中获得信息。
浏览器的JavaScript控制台
Unity WebGL 没有对你文件系统的存取,所以无法像其它平台那样写入一个日志文件。然而,它会将所有可能写入日志的信息(例如Debug.Log,Console.WriteLine 或者Unity的内部日志)写到浏览器的JavaScript控制台中。
- 对于Firefox,你可以通过在Windows系统中按下Ctrl-Shift-K 、或者在Mac中按下 Command-Option-K 打开JavaScript控制台。
- 对于Chrome,你可以通过在Windows系统中按下 Ctrl-Shift-J 、或者在Mac中按下Command-Option-J 打开JavaScript控制台。
- 对于Safari,你可以通过在Preferences中的Advanced表内启用开发菜单,然后按下 Command-Option-C来打开JavaScript控制台。
- 对于Microsoft Edge 或者Internet Explorer,你可以通过按下F12来打开JavaScript控制台。
开发模式工程
出于调试目的,你可能希望在Unity中创建一个开发模式的工程(开发模式工程选项框在构建设置窗口中)。开发模式工程允许你连接分析工具,并且他们不会被压缩,这样产生的JavaScript代码会仍然包含可读的函数名(尽管C++处理了)。当你运行到一个浏览器错误,或者当你抛出一个异常、并且异常支持被禁用,或者在使用Debug.LogError时,这可以通过浏览器显示栈追踪来使用分析工具。不像在启用完整异常支持(见下方)时你可以得到可控的栈追踪,这些栈追踪会有奇怪的名字,并且不仅包含托管代码,也包括了内部的Unity引擎代码。
异常支持Exception support
WebGL有不同级别的异常支持(查看Building for WebGL页面)。默认情况下,Unity WebGL会仅支持明显抛出的异常。你可以启用完全异常支持,这会额外选择在IL2CPP生成代码,在你的代码中捕获对空引用及越界数组元素的存取。这些额外的选项会明显影响到执行性能,增加代码大小及加载时间,所以这个模式仅推荐在调试中使用。
完整异常支持也将函数名发射来对于你的代码生成栈追踪。这样,对于未捕获的异常及Debug.Log状态,你会在控制台中看到栈追踪,并且你可以使用 System.Environment.Stacktrace 来得到栈追踪字符串。