Unity WebGL实战笔记

这篇具有很好参考价值的文章主要介绍了Unity WebGL实战笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

笔者版本为: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

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 中存在一些限制:

  • 不能在运行时启用/禁用,必须在系统发布时就确定;
  • 多重采样(multi sampleing 2x、4x…)没有作用,只有开启、关闭两个状态;
  • 如果 Camera 上又任何Post-Processing-Effect,都会引起抗锯齿失效;
  • HDR 和抗锯齿是不兼容的,如果开启抗锯齿,就需要关闭 Camera上的 Allow HDR选项。

WebGL2.0 不存在以上限制。

Enable Exceptions

Player->Publishing Settings/Enable Exceptions提供了异常处理选项

  • None 不需要异常支持,性能最好,发布包最小,但是任何错误都会引起系统停止(可以在确认没有bug的情况下再切换到这个设置);
  • Explicitly Thrown Exceptions Only : 默认设置,能够捕获由代码中 throw 抛出的异常,并且能够正确执行 finally 语句块,这将会引起生成大 JavaScript 代码更长、更慢,但这通常只在代码引起瓶颈时才要考虑;
  • Full Without Stacktrace:能够捕捉如下异常:
    • throw 抛出的异常
    • 空引用异常,Null Reference
    • 数组越界
  • Full With Stacktrace:和上面比多了一个调用栈信息,通常应该在调试阶段使用,并且在 64 位浏览器中测试。

Compression Format

Player->Publishing Settings/Enable Exceptions提供了导出文件的压缩处理选项,默认为Gzip

  • Brotli
    Google 在 2015 年 9 月推出了无损压缩算法 Brotli。Brotli 通过变种的 LZ77 算法、Huffman 编码以及二阶文本建模等方式进行数据压缩,与其他压缩算法相比,它有着更高的压缩效率。
    Brotli 压缩算法具有多个特点,最典型的是以下 3 个:
    针对常见的 Web 资源内容,Brotli 的性能相比 Gzip 提高了 17-25%;
    当 Brotli 压缩级别为 1 时,压缩率比 Gzip 压缩等级为 9(最高)时还要高;
    除了 IE 和 Opera Mini 之外,几乎所有的主流浏览器都已支持 Brotli 算法。
    brotli浏览器支持情况查询.
    Brotli压缩速度慢,且只支持https协议。
  • Gzip
    Gzip 基于 DEFLATE 算法,它是 LZ77 和霍夫曼编码的组合,最早用于 UNIX 系统的文件压缩。HTTP 协议上的 Gzip 编码是一种用来进 Web 应用程序性能的技术,Web 服务器和客户端(浏览器)必须共同支持 Gzip,当下主流的浏览器都是支持 Gzip 压缩。
  • Disabled
    不压缩,包体会比较大

服务端的配置可以参考如下官方文档:
Compressed builds and server configuration
Server configuration code samples

Data Caching

默认启用,会使用资源缓存到浏览器的 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);
    }
}

AssetBundles

WebGL 在启动之前,需要将所有的资源预加载完成,因此减少启动时间的一个有效方式就是减少系统资源,或者说减少发布资源,可以利用 AssetBundle 将资源从主包中分离出来,这样,只需要加载一个非常小的加载场景即可,另外 AssetBundle 还能帮助资源管理。

在 WebGL 平台使用 AssetBundle 有以下几点需要注意:

  • AssetBundle 中包括主包中没有的类型时,会引起资源加载失败,最好是在 AssetBundle 中不要打包新类型;
  • WebGL 不支持多线程,而AssetBundle 数据在 Http 下载完成后才可用,因此,AssetBundle 就需要在主线程进行解压缩,这会引起主线阻塞,LZMA 在 WebGL 平台是不可用的,因为它是整包压缩,可以采用 LZ4 压缩,它是单个资源独立压缩,即加载单个资源时,不需要解压整个资源包,如果需要更小的资源包格式,可以采用 gzip 或者 brotli 进行二次压缩,不过这需要 web 服务器进行相应的配置;
  • 支持 WWW.LoadFromCacheOrDownload 方法,它采用浏览器的 IndexedDB 来实现缓存;

字体

WebGL 支持动态字体,但是由于它不能访问本机文件系统,所以使用到的字体文件必须放到项目当中。(包括 Fallback fonts,以及粗体和斜体字体),另外需要注意的是,默认的Arial字体在浏览器中不支持中文(Arial字体本来就不支持中文,只是在PC或者移动端终端失败后会在设备中寻找合适字体进行替代),需要自行替换字体以支持。

为了提高性能,建议在 WebGL 中使用 TMP 来替代默认的 UGUI 文本组件,使用静态字体来替代动态字体。

发布

项目文件结构

以Default模版为例,目录结构为

  • Build
    已翻译为js的源码和相关插件
  • StreamingAssets
    项目中的 StreamingAssets 文件夹(WebGL平台下 Application.streamingAssetsPath 的值为 http://youer_host_url:port/StreamingAssets)
  • TemplateData
    包含Default模版需要的logo、进度条等UI。Minimal模版下无此文件夹。
  • index.html

持久化数据

Unity WebGL将所有持久化数据(PlayerPrefs、缓存)都保存到浏览器的 IndexedDB 中,在开发者工具中,可以通过 Application 标签页查看,这一API 是异步的,所以不知道什么时候能够完成。因此可能会遇到报错:Problem: Files saved to Application.persistentDataPath do not persist

运行index.html

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压缩。

nginx发布

若设置了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版本的问题。

WebGL稳定性

  • 不支持多线程,因为JavaScript不支持多线程,所以System.Threading命名空间下的类无法使用
  • 网络协议不支持Socket。若要在WebGL下使用网络功能可以考虑使用HTTP协议,WebSocket或者WebRTC;也可以使用自带的WWW或者UnityWebRequest,它们是基于HTTP协议实现的。
  • WebGL 1.0基于OpenGL ES 2.0,WebGL 2.0基于OpenGL ES 3.0,所以存在一定的限制。
  • WebGL音频是基于自定义的后台,因此只具备基本的音频功能。
  • WebGL是AOT,因此不能使用System.Reflection.Emit下的类型进行代码生成。

浏览器厂商为了稳定性,一般采用黑名单/白名单的方式,针对不同的显卡驱动进行功能限制,在 chrome 中可以通过输入 chrome://gpu 来查看当前 gpu 的状态,或者可以在BlacklistsAndWhitelists查询;

其它文档

Unity官方文档:WebGL
Unity WebGL 开发指北(完全篇)文章来源地址https://www.toymoban.com/news/detail-787556.html

到了这里,关于Unity WebGL实战笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity WebGL 打包il2cpp.exe did not run properly!

    是中文问题,WebGL的illcpp对执行过程中一点点的中文都不允许存在。包括 硬盘的中文名称 参考 如何更改磁盘盘符的名字 我的文档中的用户名有中文 系统用户名有中文 win+L封锁之后解锁会出现当前系统用户是否有中文 打包路径中有中文 这个很好解决 环境变量中有中文 由于

    2024年02月16日
    浏览(50)
  • Unity 2021 打包WebGL之后,用火狐浏览器打开报错,报错信息:Uncaught ReferenceError: Runtime is not defined

    Unity 发布WebGL,使用火狐浏览器打开报错 报错信息:Uncaught ReferenceError: Runtime is not defined 查找了半天的原因,发现是使用网络通讯的问题 参考网址:https://stackoverflow.com/questions/70411564/unity-webgl-throws-error-referenceerror-runtime-is-not-defined 发现如果不是使用WebSocket写的话,会不知道如

    2024年02月05日
    浏览(50)
  • Unity WebGL 关于构建webgl应用模板设置

    如果你想要修改unity 自带的webgl 启动样式,那么你需要在unity Assets 文件夹目录下添加如下目录   WebGLTemplates 目录是 unity 指定名称的目录,你可以在这个目录下新建你自己的模板目录 名字随意,然后在你需要找一下 你unity 的Default模板文件 ,在你unity 安装目录的  EditorDat

    2024年02月12日
    浏览(41)
  • unity webgl 系列(2):从webgl内存中下载文件到本地硬盘

    前面是将文件上传到webgl进程,本篇是将文件从webgl进程中下载文件到浏览器的下载目录中。 通用,只需要 二进制数组和文件名。 添加一段代码 解释:接收三个字符串:由文件二进制转换出来的二进制字符串、xxx.yy文件名、文件类型。 统一经过Pointer_stringify转化为js字符串,

    2024年04月17日
    浏览(36)
  • Unity WebGL三维地球

    1.支持arcgis,天地图,bingmap,谷歌地图,高德地图等影像加载 2.支持高程三维地形加载 3.支持在线,离线数据加载 4.支持unity坐标和经纬度坐标互相转换 5.支持fbx模型放置在地球上 6.支持倾斜摄影数据放置在地球上 7.支持pc,webgl平台发布 weixin:huazaikv 相关视频: unity三维地球_W

    2024年02月12日
    浏览(31)
  • webGL编程指南实战教程

    学习路线: 如果你是在校大学生,有足够的时间去学习:前端数学(几何+线性代数)图形学webglshader threejsthree.js源码 如果你是工作中使用,需要快速出产成品:前端threeJs。 教程主要分为四大部分: webgl容器(坐标系) webgl渲染管线 webgl关键名词 案例实战 在2D绘图环境中的

    2024年02月03日
    浏览(31)
  • Unity打包WebGL: 导入Vue

    1.1 任务 记录将 Unity 项目打包成 WebGL ,并集成到 Vue 项目中的过程。 1.2 环境 Unity : 2021.3 Vue : 2 2.1 UI 界面 2.2 添加插件 构建 WebGL 项目需要添加一个 .jslib 文件,用于 Unity 脚本函数与 JavaScript 函数交互 详细内容参考:Unity(WebGL)与JS通讯2022最新姿势 web.jslib 文件内容 2.3 添加脚

    2024年02月11日
    浏览(35)
  • unity WebGL 发布服务后出错

    解决办法:需要在IIS中添加unity3d和unityweb两个mime 1、电脑怎么添加mime 2、UNITY3D WEBGL IIS发布添加MIME类型 我在添加unity3d和unityweb两个mime后 已经解决此问题

    2024年02月11日
    浏览(45)
  • Unity WebGL发布页面报错

    1、报错内容 Unable to parse Build/test.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. 2、报错页面 解决方案,在Unity的WebGL Player S

    2024年02月16日
    浏览(38)
  • Unity WebGL获取地址栏参数

    1、在Assets/Plugins/WebGL文件夹下创建MyPlugin.jslib文件 文件内容: 2、创建脚本显示地址 3、BuildAndRun或者打包后用IIS部署一个服务器运行就行了

    2024年02月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包