赞
踩
笔者版本为:Unity2021.3.8f1
Unity提供了WebGL平台来,支持在浏览器中实时对3D图形应用交互。
Player->Resolution and Presentation->WebGL Template
默认是Default,这个模版有加载进度条,且在程序出错会弹出提示框。还有一个Minimal模版,没有进度条加载等流程,且程序出错无提示信息。
我们也可以自己自定义模版,放到Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates
目录下即可使用。
Player->Publishing Settings->Compression Format。可以设置压缩格式,一般的话会设置Gzip压缩。若无法确保服务端是否支持压缩格式,则建议设置为Disabled
Strip Engine Code可以大大降低WebGL文件大小,Unity 会扫描项目中所有从 UnityObject 继承的类型,包括检查它的内部引用以及序列化字段,将会移除没有任何引用的类型,从而减少发布大小,生成的代码也更少、更快、内存占用更少。但是要慎用其裁剪等级,需要多次测试选择合适的等级。官方文档:Managed code stripping。
对于使用了Assetbundle的项目代码裁剪很容易丢失对类的引用。运行时会看到错误Could not produce class with ID XXX
,针对这种情况一般可以按如下方式解决:
step1:根据提示 ID,查找裁剪的类型:ClassIDReference
step2:设置不被裁剪
可以在代码中强制引用一下step1中找到的类型,或者在Assets目录下创建link.xml文件,强制引用,格式如下:
<linker>
<assembly fullname="UnityEngine">
<type fullname="UnityEngine.Collider" preserve="all"/>
</assembly>
</liner>
Strip Engine Code选项只是针对 Unity 的本机代码,对于托管代码来说,总是会进行代码裁剪,IL2CPP 通过托管 DLL,以及代码脚本中的静态引用,来进行代码裁剪,如果代码中使用反射来获取类型,那么同样的,该类型有可能被裁剪掉,因此也需要添加到 linker.xml中。
默认是Gamma模式。若要使用Linear模式,则图形API只能选择WebGL 2.0
WebGL 2.0 于 2017 年首次发布。相比上一版本,WebGL 2.0在图形功能方面实现了很大提升,带来了OpenGL ES 3.0 功能集,为 WebGL 1.0 图形管道添加了对变换反馈、实例渲染、多个渲染目标、统一缓冲区对象、遮挡查询和更广泛的纹理支持的访问。
目前几乎所有主流浏览器都支持WebGL 2.0了(Safari浏览器需要iOS15+才支持WebGL 2.0)。目前笔者使用Unity版本WebGL 1.0旁标示了Deprecated。
默认情况下WebGL设置的品质比较低,锯齿感比较强,可以在性能允许的前提下通过增加Anti Aliasing级别以及设置Quality的级别来增加显示效果。但是在 WebGL 1.0 中存在一些限制:
WebGL2.0 不存在以上限制。
Player->Publishing Settings/Enable Exceptions提供了异常处理选项
Player->Publishing Settings/Enable Exceptions提供了导出文件的压缩处理选项,默认为Gzip
服务端的配置可以参考如下官方文档:
Compressed builds and server configuration
Server configuration code samples
默认启用,会使用资源缓存到浏览器的 IndexedDB 数据库,在后面运行的时候不用再次从服务器下载资源,不同浏览器的缓存策略也不尽相同。如果只是想进行空引用检查和数组越界检查,而不想完全支持异常,可以通过如下代码来支持:
using UnityEditor;
public class WebGLEditorScript
{
[MenuItem("WebGL/EnableNullChecks")]
public static void EnableNullChecks()
{
PlayerSettings.SetPropertyString("additionalIl2CppArgs", "--emit-null-checks --enable-array-bounds-check",UnityEditor.BuildTargetGroup.WebGL);
}
}
WebGL 在启动之前,需要将所有的资源预加载完成,因此减少启动时间的一个有效方式就是减少系统资源,或者说减少发布资源,可以利用 AssetBundle 将资源从主包中分离出来,这样,只需要加载一个非常小的加载场景即可,另外 AssetBundle 还能帮助资源管理。
在 WebGL 平台使用 AssetBundle 有以下几点需要注意:
WebGL 支持动态字体,但是由于它不能访问本机文件系统,所以使用到的字体文件必须放到项目当中。(包括 Fallback fonts,以及粗体和斜体字体),另外需要注意的是,默认的Arial字体在浏览器中不支持中文(Arial字体本来就不支持中文,只是在PC或者移动端终端失败后会在设备中寻找合适字体进行替代),需要自行替换字体以支持。
为了提高性能,建议在 WebGL 中使用 TMP 来替代默认的 UGUI 文本组件,使用静态字体来替代动态字体。
以Default模版为例,目录结构为
Unity WebGL将所有持久化数据(PlayerPrefs、缓存)都保存到浏览器的 IndexedDB 中,在开发者工具中,可以通过 Application 标签页查看,这一API 是异步的,所以不知道什么时候能够完成。因此可能会遇到报错:Problem: Files saved to Application.persistentDataPath do not persist
Build Settings页面Build后生成的文件index.html,双击后一般来说是无法顺利运行的。
若选择的模版是Default则会弹出报错提示界面,内容为:
Failed to download file Build/web_output.data.gz.
Loading web pages via a file:// URL without a web server is not supported by this browser.
Please use a local development web server to host Unity content, or use the Unity Build and Run option.
若模版是Minimal则无提示信息,界面空白,只能从浏览器Console查看报错日志:
Access to fetch at 'file:///C:/MetaProject/webAvatarShow/web_output/Build/web_output.data.gz' from origin 'null' has been blocked by CORS policy:
Cross origin requests are only supported for protocol schemes: http, mnt, https, nb, data, chrome, tx, chrome-untrusted, chrome-extension.
针对这个报错,若不想通过搭建服务器的方式来解决的话,目前有两种处理方式来解决。
1,依旧使用Build,且需要使用Firefox浏览器来查看(Chrome,Edge等其它浏览器都不行),而且Firefox还需要进行如下设置:
在地址栏输入 about:config,出现Firefox配置信息,在Search输入webgl
双击webgl.forece-enabled设置为true;强制开启webgl支持
双击webgl.forece-disabled设置为false (如果没有该项,则忽略)
搜索security.fileuri.strict_origin_policy设置为false;允许从本地加载资源
重启firefox
若是有如下报错,则是因为设置了Gzip压缩格式,可以通过设置压缩格式为Disabled来规避,或者勾选Publishing Settings->Decompression Fallback也可以规避该问题。
Unable to parse Build/web_output.framework.js.gz! Loading pre-compressed (brotli or gzip) content via a file:// URL without a web server is not supported by this browser.
Please use a local development web server to host compressed Unity content, or use the Unity Build and Run option.
2,使用Build And Run,unity会自己在本地搭建个服务器,且完美支持Gzip压缩。
若设置了Gzip压缩,则浏览器运行后会报错
Unable to parse Build/web_output.framework.js.gz!
This can happen if build compression was enabled but web server hosting the content was misconfigured to not serve the file with HTTP Response Header "Content-Encoding: gzip" present.
Check browser Console and Devtools Network tab to debug.
这是服务端未支持Gzip导致的。可以通过禁用压缩,或者设置Decompression Fallback来规避(实质是在发布包内集成了一个对应压缩方式的js解压工具,在浏览器解压失败会使用该工具进行解压,这样会增加加载的时间)。
若是要求使用压缩且发布包不想集成解压工具,则可以按照官方文档:Server configuration code samples把以下配置添加到conf/nginx.conf中:
# On-disk Brotli-precompressed data files should be served with compression enabled:
location ~ .+\.(data|symbols\.json)\.br$ {
# Because this file is already pre-compressed on disk, disable the on-demand compression on it.
# Otherwise nginx would attempt double compression.
gzip off;
add_header Content-Encoding br;
default_type application/octet-stream;
}
# On-disk Brotli-precompressed JavaScript code files:
location ~ .+\.js\.br$ {
gzip off; # Do not attempt dynamic gzip compression on an already compressed file
add_header Content-Encoding br;
default_type application/javascript;
}
# On-disk Brotli-precompressed WebAssembly files:
location ~ .+\.wasm\.br$ {
gzip off; # Do not attempt dynamic gzip compression on an already compressed file
add_header Content-Encoding br;
# Enable streaming WebAssembly compilation by specifying the correct MIME type for
# Wasm files.
default_type application/wasm;
}
# On-disk gzip-precompressed data files should be served with compression enabled:
location ~ .+\.(data|symbols\.json)\.gz$ {
gzip off; # Do not attempt dynamic gzip compression on an already compressed file
add_header Content-Encoding gzip;
default_type application/octet-stream;
}
# On-disk gzip-precompressed JavaScript code files:
location ~ .+\.js\.gz$ {
gzip off; # Do not attempt dynamic gzip compression on an already compressed file
add_header Content-Encoding gzip;
default_type application/javascript;
}
# On-disk gzip-precompressed WebAssembly files:
location ~ .+\.wasm\.gz$ {
gzip off; # Do not attempt dynamic gzip compression on an already compressed file
add_header Content-Encoding gzip;
# Enable streaming WebAssembly compilation by specifying the correct MIME type for
# Wasm files.
default_type application/wasm;
}
由于手机性能问题,WebGL默认是不建议使用手机浏览器的,通过Default模版出的包,一开始会弹出提示框WebGL builds are not supported on mobile devices.
,当然如果程序没问题,那么依旧是可以继续运行的。
若是想禁用Default模板下的这个提示框,可以在index.html中注释unityShowBanner('WebGL builds are not supported on mobile devices.');
即可。
但是笔者在iOS手机safari浏览器运行后弹出了报错窗口(需要使用Default模版才会有报错窗口,Minimal模版无报错窗口,因此为了调试方便一开始开发建议使用Default窗口),内容为:
RuntimeError:call_indirect to a null table entry(evaluating 'dynCall_iiii(index,a1,a2,a3)')
...(略)
Fatal error with WebGL running on 15.4?,这里找到了相关缘由,是iOS设备15.4版本的问题。
浏览器厂商为了稳定性,一般采用黑名单/白名单的方式,针对不同的显卡驱动进行功能限制,在 chrome 中可以通过输入 chrome://gpu 来查看当前 gpu 的状态,或者可以在BlacklistsAndWhitelists查询;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。