unity webgl开发踩坑——从开发发布到优化

Posted xiaoLongww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity webgl开发踩坑——从开发发布到优化相关的知识,希望对你有一定的参考价值。

目录

前言

又是一个阳光明媚的早上,突然老板召集开会说要将一个android项目适配webgl,没办法赶紧用unity改一下踩踩坑;这里记录一下这些天的踩坑过程。

环境

使用unity2021.3.4f1c1,visual studio2019,visual studio code

unity webgl的一些注意点

videoplayer修改——》Video Player WebGL插件

videoplayer仅适用于安卓和PC,如果有苹果适配的需求的话,那就要用到这个插件:unity商店——Video Player WebGL
不过,还有一些点要注意,这些在Video Player WebGL的说明文档最后也有说,我这里省流一部分:
(1)safari不支持有声视频自动播放,必须用户点击,使用pointerDown事件
(2)safari同时只能1个有声视频播放
所以,我这边的方案是:使用静音自动播放;播放结束后调用VideoPlayerWebGL.CreateVideo重新生成新video来播放下一个视频,从而实现切换。

 public void MYchange(VideoPlayerWebGL newone)
    

        if (nowIndex >= videoData.clips.Length)
            nowIndex = 0;
        newone.CreateVideo(VideoPlayerWebGL.srcs.StreamingAssets, $"videoData.clips[nowIndex++].mp4", newone.crossOrigin,
            newone.autoplay, newone.loop, newone.muted, newone.volume, newone.pan, newone.forceMono, newone.playbackSpeed, newone.targetTexture, newone.events);

    

另外,videoplayer需要注意下面这些点:
(1)使用url读取播放,不能直接引用,否则播放不了
(2)将视频打包成AB再读取为clip也是不行的,必须使用url,而且url还必须是可以直接访问的视频!

text修改——解决不能显示汉字问题

不能使用默认字体,要下载个TTF字体来使用

制作、读取ab包

(1)这里有个坑,因为楼主使用的是URP,所以在编辑器中读取AB包时会变成粉色,需要调用脚本,脚本来源自文章最下面的参考部分:


#if UNITY_EDITOR
    public static class AssetBundleEditorUtil
    
        public static void FixShadersForEditor(GameObject prefab)
        
            var renderers = prefab.GetComponentsInChildren<Renderer>(true);
            foreach (var renderer in renderers)
            
                ReplaceShaderForEditor(renderer.sharedMaterials);
            

            var tmps = prefab.GetComponentsInChildren<TextMeshProUGUI>(true);
            foreach (var tmp in tmps)
            
                ReplaceShaderForEditor(tmp.material);
                ReplaceShaderForEditor(tmp.materialForRendering);
            

            var spritesRenderers = prefab.GetComponentsInChildren<SpriteRenderer>(true);
            foreach (var spriteRenderer in spritesRenderers)
            
                ReplaceShaderForEditor(spriteRenderer.sharedMaterials);
            

            var images = prefab.GetComponentsInChildren<Image>(true);
            foreach (var image in images)
            
                ReplaceShaderForEditor(image.material);
            

            var particleSystemRenderers = prefab.GetComponentsInChildren<ParticleSystemRenderer>(true);
            foreach (var particleSystemRenderer in particleSystemRenderers)
            
                ReplaceShaderForEditor(particleSystemRenderer.sharedMaterials);
            

            var particles = prefab.GetComponentsInChildren<ParticleSystem>(true);
            foreach (var particle in particles)
            
                var renderer = particle.GetComponent<Renderer>();
                if (renderer != null) ReplaceShaderForEditor(renderer.sharedMaterials);
            
        

        public static void ReplaceShaderForEditor(Material[] materials)
        
            for (int i = 0; i < materials.Length; i++)
            
                ReplaceShaderForEditor(materials[i]);
            
        

        public static void ReplaceShaderForEditor(Material material)
        
            if (material == null) return;

            var shaderName = material.shader.name;
            var shader = Shader.Find(shaderName);

            if (shader != null) material.shader = shader;
        
    
#endif

修改一下即可;
(2)坑二:发布时勾选enable exception---------explicitly thrown exceptions only,否则加载ab包报错,目前原因不明
(3)读取需要使用unitywebrequest

unity audioclip减小建议

如果在移动端观看,240P都蛮清晰的(看个人)

减小包体 全过程记录

1、一开始有207MB
2、压缩纹理、将TextMeshProUGUI改为Text后,剩下111MB
3、删除Resources文件夹中无用的东西,将预制体、场景中隐藏的模型删除,剩下101MB
4、将每个场景中的环境模型做成预制体,然后打AB包,剩下64MB
5、将场景中videoplayer的直接对videoclip引用移除,改为读取url,剩下16MB

webgl的build

过程各位应该很熟悉了我就不多说了,关键的地方截图几张好了


webgl部署到本地、云(IIS)

具体过程可以看下面的参考,主要注意几个点:
(1)最好新建站点来搞,楼主有试过将webgl部署在有.NET CORE API站点的wwwroot上,结果发现一直报404,填了MIME也没用,目前暂不知道什么问题,欢迎各位大佬评论!


(2)经常说的Mime添加一下:.unityweb、.data、.unity3d
(3)测试用的免费云我也放一下这里: uniCloud

webgl部署云如何提升加载速度

使用公司的云,带宽3M,结果加载1个10几M的unityweb文件都要接近1分钟,这种情况可能要考虑加带宽或者使用CDN服务比较好。先开个章节后续补充。如果有同样经历的大佬也欢迎评论!
顺便一提,免费云有CDN,加载时间差不多7、8秒,快的离谱。。

webgl的一些其他需求

webgl改模板

先按照这个链接获取默认模板,然后需要拥有一定的js知识来修改index.html
这里我的需求是移除进度条和移动端提示,所以改两个地方即可:

webgl在移动端横屏

需求:手机浏览器上打开,当手机屏幕旋转为横屏时,网页也能自动旋转,且画面正常。
这个要高版本的unity就可自动实现,最好用2021.3.15f1c1,以下是从2021.3.4更新到其他版本unity的奇怪错误:

更新到2021.3.13

下面这些方法都不行:

  • unity商店上的插件ScreenOrientationWebGL(据说Safari on ios不能横屏,需要考虑对UI做适配——不能横屏则启用较大的UI)
  • 直接使用unity原生API——Screen.Orientation (不支持WEBGL,因为project setting里面webgl平台没有landscapeLeft这些类类似的选项)
  • github工程UnityWebGLOrientationDetectSample-main

webgl全屏

全屏功能仅在安卓机型起作用,苹果机型不起作用!
(1)在PC全屏,需要改模板,或者改index.html,PC内容全屏:不包含标题栏
油管视频跟着做就行
(2)在移动端全屏,需要通过点击按钮事件触发。这里我是通过在unity的UGUI调用Screen.fullscreen来实现的。查阅资料得知,出于安全考虑,浏览器仅在直接响应用户启动的事件(如鼠标单击或按键)时才允许锁定光标或切换到全屏模式。
unity文档-浏览器全屏介绍

PS:苹果机型横屏会有白边,全屏无效

推荐一个插件,更方便地监听全屏时的回调:unity商店——FullscreenWebGL

webgl性能分析

(1)当然是大家最熟悉的unity profiler了,可以先在编辑器分析一波,然后再发布develop版本,在移动端上也测试一波
(2)PerfDog:好用是好用,贵也是真贵,不愧是我饿厂 使用方式可以在官网查到,这里我分享一下 PerfDog连接苹果手机的方式:

  1. 安装iTune,下载Pefdog
  2. 连接手机,手机打开开发者模式,更新iOS16后,iPhone怎么开启开发者模式?
  3. 选择测试应用即浏览器即可

webgl优化

内容比较多,我上传个文档免费下载吧
本站——UNITY WEBGL的优化心得

总结

总的来说,这次还是学了不少东西,踩坑也踩麻了 也欢迎各位朋友多评论。那么我们下一篇文章再见吧!

参考

unity官方-webgl发布的基本设置
unity官方-webgl包体减小的基本措施
unity官方-各平台纹理压缩建议
梵佬的读写AB包文章
外网大佬的关于URP编辑器中读取AB包粉色的应对脚本
关于webgl包体减小的尝试
水光大佬的webgl发布到阿里云
知乎大佬-webgl一篇比较全面的指南

Unity开发踩坑-粒子特效(ParticleSystem)性能优化

开游戏开发中,会常常遇到用粒子特效来制作技能特效,子弹特效,或者装备特效等。
但是对于初学者来说常常会遇到如果屏幕出现大量同一个特效时,会遇到性能的问题不知道怎么优化。

今天我就来举个例子带着大家一起尝试优化出现大批量例子特效之后遇到的性能问题

例如:我们在游戏中有一个例子特效 这个特效采用3种不同的材质球如下:

我们开发帧调试器(FrameDebug)看看当前的情况:对于FrameDebug如何使用,里面的信息代表什么意思,我们后面的文章再来介绍。

由图可以看出当前的三个粒子对应了三个不同的 DrawTransparentObjects
透明对象:由于我们材质球采用的是SurfaceType是 transparent 所以在渲染绘制时 处于 DrawTransparentObjects这个层级。
此时,我们将当前的这个粒子特效多复制几分看看情况

由上图可以很明显的看出:
虽然我们都是一模一样的例子特效,由于我们复制了23份出来 那么渲染帧调试器的透明对象,比最初多了很多很多。
这是不符合,我们优化时的规律的:同一个材质球,在渲染时,竟可能全部合批处理

这时候细心的同学可能会问,复制了23分 +最开始的一份 = 24*3=72个 DrawTransparentObjects,为什么图中只有60
疑,渲染帧中怎么出现了Draw Dynamic

我们看镜头中DrawCall 为 3 那么我们在看看其他的DrawCall为多少

通过图可以看出 是不是没有? 没有就是默认DrawCall为1的意思,那么就奇怪了 为什么有的为3有的为1呢?
这就是我们本文中要提到的粒子特效合批优化的内容
来跟着我一起简单的把当前粒子特效修改一下




跟着我入上图,将每个粒子用到不同材质球的 OrderInLayer 划分为单独一个层
再运行看看渲染帧:

是不是神奇的事情发生了,渲染调试器的DrawTransparentObjects 有最初的60 变了3个, 正好我们当前粒子特效只有三个材质球。
然后每一帧里面的渲染对象突然大幅度猛降 。 那么我们对粒子特效优化的效果是不是就达成了。

重点:其实在调试渲染帧调试器时,不管是粒子特效,还是模型对象,优化的思路都一样,就是要将同一材质的对象,想办法放一块(也就是将渲染层级调到一起),那么URP在做渲染时,就会自动将相同材质球的内容给我们优化掉。 我们没有调整粒子特效的渲染层级时,三个粒子的渲染层级都是0,那么在绘制时,就是按照顺序往下绘制,正好我们三个材质球的顺序都是 1 2 3这样隔开的,所以相同的材质球没办法在一块,我们就需要手动调整粒子的渲染层级(模型的优化原理也一样)

对于什么URP在渲染时,时按照这样的顺序来的,我这儿要推荐一个unity官方视频讲解 引擎底层的渲染逻辑内容:
00:25:50 《SRP底层渲染流程及原理》by Unity高级解决方案工程师 李中元
该视频看了之后再看我这篇文章,就很容易秒懂。

但是有一点得注意:URP中相同材质球合批处理了 不是说我们真实的drawcall就降低了 我们可以看到 单个里面的drawcall 是24
另外三个也是24*3 = 72
如下图所示:URP是通过减少每一帧中,CBFFER环境的数量来提升优化,也就是说,在一帧里面,渲染同一个材质球的24个drawcall打包一起,传入到了GPU。前提的是SRP Batch开关要开启

如何打开:SRP Batch的开关,找到UniversalRenderPipelineAsset文件如下图

如果需要深入理解URP里面的内容可以看UNITY官方的教程
https://blog.unity.com/technology/srp-batcher-speed-up-your-rendering

本次结束到这儿,喜好的朋友麻烦点一健三连,谢谢。
UNIYT技术交流群 QQ群:68356214

以上是关于unity webgl开发踩坑——从开发发布到优化的主要内容,如果未能解决你的问题,请参考以下文章

unitywebgl允许http没有响应

Unity开发WebGL内存概念详解和遇到的问题

教程Unity WebGL 内存优化:续篇

[蛮牛教程] Unity WebGL内存优化:Deux部分

Unity开发踩坑-粒子特效(ParticleSystem)性能优化

Unity游戏开发性能优化之在真机上开启DeepProfile与踩坑