Unity-发布WebGL平台的问题记录
1.webgl不显示字体
开始导出来发现一些字不显示,还以为分辨率压缩Text文本导致字不显示,后来发现原来是webgl的问题,查阅信息说不要使用unity自带的字体,用下载好的包含中文字体,放在项目文件中。
2.webgl无法输入中文
有不少插件是能在非全屏状态下正常输入的,插件地址:Unity WebGL中文输入插件 支持输入法跟随,这个插件算是功能比较完整的了,唯一不足的是unity默认导出的webgl使用该插件是不支持全屏下输入的,会出现很多错误,比如输入光标错位、报异常。所以还需要另外一个插件,百度搜索Universal WebGL template,网上有很多免费的,两个插件结合基本就完美解决了所有问题。
3.字体模糊
这个比较常见,unity默认使用Text的字体放大就会很模糊,甚至看不清,解决这个问题的办法就是使用TextMeshProUGUI插件,这个插件可以在PackageManager里下载,这个插件的优点是:1.你可以自己制作不同的字体;2.无论放大多少倍,或者字体大小很小时,都会很清晰的显示;
4.webgl导出包浏览器打开报错超出内存大小
做成webgl的项目或多或少会出现这样的错误,经查找官方资料,使用unity2018版的可以调节导出包使用内存的大小,unity2019版本开始就删除了改变内存大小的值,然后找到有个解决办法是代码改变内存大小,于是小编发现Universal WebGL template模板下有段代码(77:TOTAL_MEMORY: 268435456,)被注释了就是改变内存大小的,然后试着加大内存的值,在火狐浏览器是可以正常打开的,然而在Google浏览器就直接报另外一种错误,欲哭无泪,甲方要求使用的是Google浏览器,只能另寻其他办法,最后找到的解决方案就是使用Asset Bundle来加载包,减少包的大小,减少内存的使用。
5.webgl使用Asset Bundle加载资源模型材质显示异常
刚开始导出webgl包和ab包,使用浏览器加载,然后发现一片红啊,使用ab包加载的有一部分模型材质显示为粉红色,第一反应就是材质丢失,以为是ab包卸载了材质的资源,然后经过更改代码不使用卸载,发现还是一样。。。那就不是这个原因了,网上查阅了一些资料,发现原来需要将相关的shader添加到ProjectSettings->Graphics->Always Included Shaders里,切记将unity Standard材质包含在内,不然你会发现你导出webgl包会非常慢并且你的包的大小会很大,因为它包含了成白上千种shader,所以这里尽量少使用Standard,使用也可以,就是效果会变化,在编辑器显示很好,导出来就跟换了一种shader一样,尽量使用其它可以替代它的shader,或你可以去编写shader,或使用ShaderGraph插件编写的shader,然后包含在这里就可以了,这样导出速度快且包小。
6.webgl使用Asset Bundle加载资源的一些注意事项
使用Asset Bundle Browser插件,可以在PackageManager里下载,使用教程网上也有很多,这个插件小编觉得蛮好用的,可以显示不同ab包是否有重复的资源,让开发者减少ab包的大小。下面是使用ab包的一些注意事项:尽量使用多个ab包,且每个ab包大小不要超过20M,使用ab包分类管理;尽量不使用阻断协程的方法来加载ab包;ProjectSettings->Player->Strip Engine Code不要勾选;加载后注意要记得UnLoad(false),减少内存的使用;ab包使用的shader要包含在ProjectSettings->Graphics->Always Included Shaders里;使用LZ4压缩。
7.webgl播放视频
这个算是比较简单,网上插件也比较多,unity自带的VideoPlayer,可以播放本地视频和Url,注意需要一开始时不要勾选Play on Awake,在浏览器会播放不出视频,我使用的是AVProVideo,这个插件还不错,支持PC、android、IOS、Webgl、Mac等平台,可以自行选择,网上教程也有很多,同样注意开始时不播放视频。
8.webgl播放视频流实时视频
项目中有播放rtsp视频流的要求,然后查阅了一些资料,找了半天就看见一个插件UMP Pro Win Mac Linux WebGL ,用了之后发现webgl好像不支持,实属垃圾,后面找到一篇Unity WebGl播放m3u8在线视频(监控,直播)解决方案,这篇很不错,想学习的可以试试。
9.webgl json序列化和反序列化问题
使用unity自带的JsonUtility.FromJson()解析json数据在编辑器可以很好的解析,即使定义为int型数据,数值为Null,这个在webgl里也可以解析,但是有些数据结构是不能正常解析的,比如Dictionary字典,在编辑器能正常解析,但是在webgl里就不能正常解析了,后面找了另外一个Newtonsoft.Json来解析,这个可以正常的解析字典数据,但是要求你定义正确,unity自带的JsonUtility.FromJson()不需要定义属性正确,可能还会出现某些人给你的接口定义某属性是int型,但是给的数据却是null,这类人也不少吧,那怎么办呢,使用Newtonsoft.Json来解析就会报错,说这个属性定义错误,也是崩溃。。。好在查找资料有这个解决办法,就是使用int?来定义,其它类型float?、long?都可以这么来定义,这样就可以解决这个问题了。
10.webgl+nginx搭建简单服务
打包出来的webgl有些浏览器是不支持直接打开的,Google和火狐浏览器就不能直接打开,所以需要搭建简单的服务器来打开webgl网页,下面一篇文章很好的解决这一问题unity webgl + nginx服务器 You can reduce your startup time if you configure your web server to host。
11.webgl解决模型锯齿问题
模型锯齿问题unity自身的解决方案是:Project Settings->Quality->Anti Aliasing 选择8x Multi Sampling,Quality 记得选中webgl平台下你设置好的选项。当然还有一些插件都会有抗锯齿的优化,比如PostProcessing后期处理特效的插件,有兴趣可以试试。
12.webgl调式
相信开发webgl项目的朋友应该都知道,在编辑器下编写能正常运行,但是呢导出webgl一运行就会发现各种错误,恨不得unity出一个在网页上测试使用的编辑器,配合VS一段代码进行调式,但是这是不可能的,所以就尽量使用debug来定位错误吧,小编也是被折磨的不行,因为某些功能只能在特定机器上部署测试,这使我代码出错了只能写debug来定位了,所以多写一点,因为导出包不易啊!一次打包10分钟,想要很好的测试哪段代码出问题就得看debug了,记得勾选ProjectSettings->Player->Enable Exceptions为Explicitly Thrown Exceptions Only,不然在浏览器控制台就看不到debug了,最后正式上线记得关掉。
13.webgl性能优化
当你满怀欣喜的打开你的项目,发现你的项目就像播放PTT一样,那就的做优化了,优化有:
1.减少模型的片面数和顶点数(尽量不使用球和圆柱体这两个片面数太多了);
2.使用静态合批,勾选Project Settings->Player->Other Settings->Static Batching,相应的物体Static需要勾选Batching Static;
3.使用动态合批,勾选Project Settings->Player->Other Settings->Dynamic Batching,相应的物体Static需要勾选Batching Static;
4.贴图如果模糊的话,去掉勾选Generate mip map,尽量将MaxSize减少;
5.去掉阴影,使用光照贴图;
6.如果模型的材质不需要受到光照影响,尽量使用Mobile/Diffuse或者Unlit/Texture;
7.尽量删除碰撞体;
8.删除没有用的Animator(有些模型导入会有);
9.尽量少使用Animator,简单的动画使用Dotween或者使用Animation,繁琐的、多状态才使用Animator;
10.删除网格碰撞,尽量不使用网格碰撞;
11.使用光照烘焙,使用Reflection Probe和Light Probe Group,属性设置完成后,将需要受光照影响的模型放置里面,在lighting面板点击bake即可(物体删除都可以,数据已经存在Scene数据里了);
12.使用遮挡剔除,物体放置在Occlusion Area,static勾选Occluder static和Occludee static,在Occlusion面板进行bake即可(物体删除都可以,数据已经存在Scene数据里了);
13.开始运行时尽量少使用new;
14.使用LOD(这个不太推荐使用,只有内存充足下使用,一般webgl内存都是吃紧的,搞不好就是内存超出)。
14.加载本地文件
前端html中使用
<input type="file" id="files" style="display:none" οnchange="fileImport()">
前端js
URL.createObjectURL(file)
发送给unity
unityInstance.SendMessage("TestObj", "SendUrl", file.name+"|"+URL.createObjectURL(file));