查看原文
其他

Unite 2019 |《球球大作战》优化之路(上)

王国祎 Unity官方平台 2022-05-07

自从2015年《球球大作战》发布以来,现已拥有五亿多的玩家。如此庞大的玩家群体,对游戏的画面,性能要求是非常高的。在Unite Shanghai 2019大会中,《球球大作战》客户端主程王国祎和资深技术徐宇峰带来了关于《球球大作战》优化之路。


本文将分享《球球大作战》客户端主程王国祎演讲部分,他将分享《球球大作战》升级到Unity 2017版本遇见升级问题和资源问题,以及如何去处理解决


演讲内容

大家好,感谢大家来听我们的分享。我是《球球大作战》客户端主程王国祎,主要负责《球球大作战》的客户端开发。之前都是以听众角度参加Unite大会的,这次作为一个演讲嘉宾过来参加,感觉体验还是不太一样,很有新鲜感。

 

简单介绍一下《球球大作战》,这是一款多人休闲竞技游戏,主要强调多人合作玩法,玩法简单上手,但想要达到高的级别或段位,还是比较困难的。

 

《球球大作战》发布于2015年,当时很多游戏的玩家现在都上了初中或高中。就像《超级马里奥》或《魂斗罗》可以成为我们这一代人的回忆一样,我也希望《球球大作战》能成为他们的长久陪伴,这也是我创作游戏的初衷。



1

升级Unity 2017

《球球大作战》早期使用Unity 4.7开发,所以整个表现效果都是Unity 4.7版本,后来我们也尝试升级了Unity 5的版本,但发现问题还是比较多,所以我们去年做了Unity 2017版的升级,我们会在下面分享升级过程遇到的一些问题,后面还有优化的过程和新的方式。

 

先讲第一部分,是我们升级Unity 2017遇到的一些问题。最开始我们也尝试升级Unity 2018版本,我们试了Unity 2018.1和Unity 2018.2,在转换过程中的问题还是可以接受的,但上线测试时发现了兼容性问题,最后我们还是选择使用比较稳定的版本,也就是Unity 2017.4.3。


小提示:Unity每个周期会有3个TECH技术前瞻版本和1个LTS长期稳定支持版本,Unity一直建议对已发布的游戏采用LTS版本,也就是Unity 2017.4或者Unity 2018.4,从而避免遇见上文提到的兼容性问题。请阅读:Unity全新的版本发布计划


为什么选择Unity 2017呢?主要是因为它和Unity 4.7有一些不同的地方。



1、ASTC图片压缩格式

我们一开始尝试在Android和iOS同时使用该格式,后来经过大量测试发现Android不支持这个格式机型占比很高,最后在Android系统上还是使用原有的ETC和ETC2格式,只在iOS上使用ASTC格式。


iOS在iPhone 5S及以下机型硬件会走原解压的过程,整个图片的加载速度会比之前稍微慢一些,但我们觉得速度测试下来还是比较理想的,所以还是坚持在iOS系统使用ASTC格式。

 

2、Bundle LZ4的压缩

在Unity 4.7版本时,我们基本是不做压缩和解压缩的,中间会用LZMA做传输过程的压缩,这样在压缩和解压方面不会占用时间。


到了Unity 2017.4后,因为它本身就支持LZ4的压缩,不管从解压速度和内存大小来说,它都是很少的,所以我们最后决定用LZ4。

 

3、Bundle文件的异步加载和读取

在使用Unity 4.7时,我们在加载非压缩文件时是走同步的方式,因为本身Unity也没有做异步加载Bundle的接口,但是Unity 5.x以上版本就支持这个接口了,所以我们这边Bundle是使用了异步加载的方式。

 

4、运行时设置分辨率

我们有一些优化测试下来发现,该游戏本身手机的分辨率可以达到很好的提高帧率并降低消耗的效果。


Unity 2017.4和Unity 4.7在设置分辨率有一个很大的不同是,之前在Unity 4.7降低分辨率时,在Android系统会出现闪一次黑屏现象,这在Unity 2017.4上是没有的,所以我们可以用这个特性来动态调整屏幕的分辨率。


在特定场景中,例如:高渲染的场景中,可以动态调低分辨率,使用户可以在没有感知的情况下提高帧率。

 

5、Camera RT缩放分辨率可提高帧率

在Unity 4.7上我们尝试过在Camera缩放分辨率,但是没有效果。在Unity 2017之后,我们尝试这个方式发现效果比较明显,发现平均帧率可以提高15帧左右。但是带来的问题是,可能显示上有稍许的差别,没有原始的不改分辨率的情况好。

 

6、Android支持IL2CPP

Android支持IL2CPP主要是为了Google之后发版本的。

 

7、支持GPU Instance

我们在年初的时候制作一个3D的玩法,如果是Unity 4.7的话,这个玩法在我们的机子上就爆表了,因为同场景渲染的动作非常多。


在升级到Unity 2017时,使用GPU Instance帮了很大的忙。尤其在动作处理这块,可以动态合批,然后它合成的效果非常好。

 

8、动画系统可以对指定区域缩放

最后一点也是美术吐槽非常多的,那就是Unity 4.7动画调整的时候,不能对指定区域进行缩放,它只能一帧一帧地调,这是升级后缓解最大的一点。


Q1:游戏帧率降低

下面简单说下升级2017后遇到的一些问题,这些问题是我们没想到会发生的。因为我们想:升级引擎只是对一些资源,效果会有一些提升,甚至效率会提升。但升级完之后,测试发现在同等手机,同等内容的情况下,帧率反而会减低。



我们对问题查了很久,做了很多版本的比对,甚至对不同版本,不同客户端进行差异的比对。测试下来的效果是:Unity 2017在同等情况下比Unity 4.7要低10帧左右。这主要发生在中端偏低端的机型,正常的中端以上机型没有这个问题,甚至表现效果会更好。


我们测试问题的时候,还做了独立的只有核心玩法的版本,这个版本抛离了游戏以外的系统,只有核心玩法。这样是想更好地测试过程,并尽快地排除问题,


因为这些问题比较难发现,所以这个版本一直是我们测试的核心版本,而且这个版本也做了动画录制的功能,把每一局的表现的协议和脚本都录制下来,每一局都是自动播放,这样循环地查看问题,查看每个帧率的表现,最后找到这些问题。

 


有几个选项上的切换,一个是Android上的Blit Type


Blit Type选项在Unity 2017版本上是2.0之后开放的,也就是说2.0之前是没有这个选项的。我们测试时发现,把这个选项关掉后,帧率确实提升了很多,提升了5-6帧左右,我们发现它对中低端硬件的渲染影响还是比较大的。

 

我们与Unity官方技术支持交流,他们说针对不同的游戏,这个选项可能选择自动的会比较好。但是测试下来发现,可能因为我们的游戏对3D和渲染光照方面使用的不是很多,所以去掉该选项,使用Never可能效果会更好。



因为我们的游戏表现上看起来是一款2D游戏,所以对镜头上的HDR和抗锯齿MSAA不是很实用,所以我们会在Camera组件中,去掉勾选Allow HDR和Allow MSAA这二个选项。


还有光照这块,因为游戏没有使用实时光,所以我们在Lighting设置去掉Realtime Lighting和Mixed Lighting选项。调整了这些选项后,帧率持平了原来的游戏表现。



Q2:资源问题

下面是转换上的资源问题。球球到现在为止的皮肤总量已经超过4千多个,也就是意味着我们在转换过程中要排查每一个资源,和旧的资源去比对,会不会有显示上的问题。这是非常巨大的工作量。



这边一个问题就是,我们有一些美术同学可能前期从一些旧的资源里,使用Mesh导出的文件包含中文的命名,这是为以后埋了一个坑。


虽然在Unity 4.7里没有问题,会显示一个横杠,不会显示中文名,显示上不会有问题。但同样的资源转到Unity 2017后,显示上会出现一些引用丢失的情况。


我们分析过后,发现Meta文件中的Unicode码丢失了,所以需要手动地把这些复制过去,所以这是当时解决问题比较棘手的地方,因为当时都是手动复制的,幸好这些中文的资源不是特别多。



还有就是转换之后粒子缩放的问题。因为球球的皮肤之间是互相叠加的,叠加之后为了做相互的叠加效果,会有Z轴的压缩。所以转换之后,粒子的缩放模式变成了Hierarchy模式,根据主节点一起缩放。


这个问题导致的效果是,Z轴上的粒子表现缩放会有缩放的显示问题,会有穿插,最后表现的效果是和大小缩放后的效果不是很一致。


我们向Unity反馈过这个问题,Unity也在跟踪处理这个问题。我们现在改成了Local模式,因为我们自定义了一个缩放的脚本来控制球体和粒子放大缩小后的效果。



 Q3:打包问题

接下来分享我们碰到的一些打包上的问题。 



我们的美术资源现在有6G多,在旧版本中打包耗时非常长,耗时通常要半个小时左右。在资源量非常大、冗余之后,工程启动也非常慢。


升级Unity 2017之后,资源在打包速度和工程开启速度上都有些提升,但还是没达到理想的情况。


我们采取的方式是把老旧资源拆解到另外一个工程里面,保证二个工程的引用是统一的,Guid也是统一的。这样在老工程中的资源是不进行打包处理的,只打包新的资源,这样提高了很多打包速度,Unity打开美术工程资源的速度也会非常快。



我们在Unity 4.7导出的是一个Eclipse的项目,所以在打包时哪怕文件很多也不会有打包失败的情况。但是使用Android Studio的时候,如果使用默认设置的话,会出现打包失败


这个失败问题比较奇葩,它不会给你提示错误,只是打包时间非常非常漫长,甚至在最后没有结束的时间。


我们也查了很多资料了解这个问题,最后发现是要调整缓存,在打包Android Studio时,如果本身包含的文件非常多,要记得把缓存改大一些,要不然打包时会有问题



在导出iOS工程时,我们会导出XCode工程,发现每次导出时Framework Search Paths的目录,就是库引用的目录每次都会被清空。


我们有很多第三方的库是需要被引用的,而且打包是自动的,iOS这边导出后会自动设置好,所以后面改了方法,是在导出时使用PBXProject.SetBuildProperty方法,把需要引用的库再动态地添加上去,来解决这个问题。



客户端版本

这是我们测试的一种方式。我们游戏对玩家手感操作的敏感度可能非常高,也就是说,如果一个版本发布后,和之前的手感有所差别,对我们是比较灾难性的结果。


所以我们测试使用二个版本,一个叫预览版,一个叫正式的线上版。玩家正常玩的都是线上版,然后我们会推送给玩家预览版,预览版的账号和服务器是通用的,只有客户端不同,一个是普通的是Unity 4.7版本,另一个是升级之后的Unity 2017的版本。


我们让玩家体验这二个版本,并且给反馈,因为玩家会在同一个手机上体验二个版本,所以给出的反馈都是比较真实的,都是比较及时有效的。我们觉得这个方法是最有效的测出问题的方法。



版本兼容,渠道更新

我们线上其实一直存在二个版本,因为我们早期尝试使用过5.x版本去升级。当时做完后发现效果并不好,而当时盲目乐观地直接用5.x版本进行开发,导致新制作的资源都回退掉了。


我们进行Unity 2017版本升级的时候,直接拆成了二个版本,也就是说正式开发过程还在Unity 4.7上,无论是美术还是程序,都在老版本开发。


线上还会同时存在老版本和新版本,开发的内容和功能在Unity 4.7版本更新好后会合并到Unity 2017的版本,并同步更新出去。二个版本一般会有三个月的兼容期,尽量让玩家把测试期缩短,让玩家在里面反馈问题。

 

我们会在部分渠道先上传一些版本,然后小范围地进行更新,目的是不影响玩家的情况下进行更新,担心新版本的兼容性会存在问题。



2

球球优化

下面讲一下球球的优化,前面我们讲了球球的升级,其实升级的目的是想通过升级的一些手段去做新一轮的优化。


以前我们会从技术角度去做问题的排查和优化,例如:玩家网络有问题,反映延迟很高。我们觉得把TCP换成UDP,并且调到比较好的主干网络或机房网络,会解决这些问题。其实并不然。

 

有一次我参加《球球大作战》的见面会,一个玩家吐槽他连接自家WiFi时非常卡,延迟非常高。他上网查问题,搜了一些帖子,发现有人回复说把防火墙关掉,他尝试后发现真的好很多。出现这个问题我想的是可能他的网络把UDP常用端口屏蔽掉了,然后只能走不是UDP常用的端口。


通过这个问题,我们发现玩家往往发现的问题不是我们要优化的点。我们从技术角度想的一般是网络上换一个网络底层,把DrawCall降低,以为这样就解决了问题。其实并不是,我们要从玩家的角度去查找到这些问题


制定美术资源标准

我们之前的美术标准都是一刀切,例如:最高不可以是多少Drawcall、面数、骨骼数。


但美术在制作资源的时候,如果低于这个标准,例如很简单的资源,美术会觉得反正低于这个标准,那么就多加一些特效。如果超过这个标准,但是又是重点的付费道具,短时间无法优化好。


我们总结发现,美术资源标准要差异化


下图是我们新制定的美术标准。



对于美术或游戏来说,我们的道具分普通的道具和炫酷的道具,我们要把档位精细化,有界定的指标确定一般的档位是多少,然后是比较炫酷道具的指标,再定最大指标。


这样美术操作时会觉得比之前灵活很多,会知道自己制作的资源属于什么档位,然后按档位去做优化。


LOD优化

还有就是针对游戏的LOD优化,因为《球球大作战》看上去更像是一个2D游戏,和3D游戏的LOD优化不太一样。

 

我们使用的方法是皮肤像素占屏幕像素的比例差,进行高低品质资源的切换,在球体非常小的时候,我们会提供低配的提前渲染好的图片。


因为我们试过简化特效粒子,发现不管是工作量还是效果都不是很理想,后来我们发现玩家主要注意的视野都是大球,而不会很关注小球。所以我们采取的方法是,提前渲染好图片,替换到比较小的资源上,在玩家球体很小时,使用图片渲染。



手机性能分类

对于手机机型划分,很多优化方式对玩家或多或少有影响,所以我们想针对不同机型对游戏做优化。最开始其实没有按机型分,因为我们觉得机型太多无法划分。


我们的方法比较投机取巧,那就是使用CPU型号去做手机型号分档。网上可以找到CPU梯度图,不同CPU在不同档位,只要获取玩家的CPU信息就可以对应到不同的档位里面。


但测试后发现这个方法不太乐观,因为我们遇到一个现象:有的手机CPU处于中档,但是屏幕分辨率却非常高,这时会出现整体性能表现降低的现象,所以我这种方式不太靠谱。


 

我们最后选择的方法是:由于游戏运营已久,有大量的玩家帧率卡顿日志,所以我们通过玩家的帧率、每局游戏得到帧率差值、最高最低值等,决定该局游戏的帧率范围。


然后过滤出来手机在运行时是处于高档机型、低档机型、还是中档机型。这个分档比较靠谱,虽然这样涉及机型较多,但准确性比之前的方法高很多。

 

我们发现周边的同事都在不停的换新款手机,所以我们会习惯认为玩家的手机也在不停更新换代。通过游戏数据我们发现千元机占了60%多的用户,这也让我们把优化重点放在这些手机型号上。


网络卡顿

下图是我们每局结束都会上报的网络使用情况,我们还没对数据做处理,而是对上报结果进行分析。


我们觉得玩家手机使用4G基站网络,或使用WiFi,过程是路由器到主干网,主干网到游戏服务器。这只是把主要网络情况监控下来,后期会做一些筛选和定制化的策略,例如一些提醒,这是我们后面要做的事。


小结

在《球球大作战》优化之路的下篇中,我们将继续分享本次演讲巨人网络资深技术徐宇峰讲述后期游戏制作中的优化方式,敬请期待。


更多Unite大会精彩内容分享,尽在Unity Connect平台(Connect.unity.com)。

 

下载Unity Connect APP,请点击此处。 观看部分Unity官方视频,请关注B站帐户:Unity官方


推荐阅读

《使命召唤手游》,引擎技术升级与演化

Unity中的实时光线追踪技术剖析

《崩坏3》:在Unity中实现高品质的卡通渲染(下)

从《闹闹天宫》看MOBA游戏里的网络同步技术

使用Unity的VR功能创作交互式媒体体验

针对Linux系统的Unity编辑器介绍


有奖调查

Unity Hub 2.0中文版以及Unity中文版文档已发布,请参与有奖调查,反馈你的意见,以便我们进一步改进。更多详情,请访问此处。



点击“阅读原文”访问Unity Connect

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存