153848hy9gpys9yrgf5sgi.png
文/侑虎科技

今天我们为大家带来由福州朱雀网络研发的MOBA手游《小米超神》的UWA测评报告分析。该游戏在不同配置的移动终端设备上,无论是画面表现力,还是性能开销都非常优异。在此,我们将对该款游戏的性能数据进行深度剖析,希望通过这篇文章可以让大家对移动游戏各个模块的运行效率有更为深刻的认知,并对大家的项目研发有所帮助。

一、CPU性能

该游戏在CPU占用方面的性能非常不错,下图为该游戏在红米Note2设备上进行一场5V5战斗时的性能数据。

153913r1pfjpy1bsb2c21p.png
2、UI模块

该游戏在红米Note2设备上运行时的UI模块CPU开销如下图所示。该游戏使用UGUI作为UI界面的解决方案。经过统计,UI模块总体的CPU占用均值为1.5 ms,主要集中在0.1~3.5 ms(5%~95%),属于合理范围之内。堆内存累积分配为16000帧 2.4MB,平均每帧分配堆内存155.4B,这说明该游戏UI界面的制作及UI重建的影响范围非常合理。目前,UWA推荐UGUI模块中,平均每帧堆内存分配尽可能控制在200B以下。

153916o8ioc388lczonlpf.png
4、GC 调用

该研发团队对于GC调用频率控制得非常出众,游戏在运行过程中,GC调用频率为1656帧/次,优于目前93%的行业内游戏。一般来说,我们建议一款项目的GC调用频率可以控制在1000帧/次以上。

153918afofmdxkgkbfncf6.png
当前版本的堆内存分配仍然有进一步下降的空间,从堆栈信息中可以看到,其Log输出仍然存在一定堆内存分配,建议研发团队在Release版本中将非关键性Log进行屏蔽。

153919lfy0mzpyunxnn108.png
二、内存模块

《小米超神》在内存上的表现如下图所示。总内存峰值达到297MB,Mono堆内存峰值为48.9MB。297MB的总内存分配相对来说略高,研发团队可尝试在低内存机器上对资源进行进一步控制,从而降低低内存机器上的内存占用。

153920lga69yhfxwnjg8ym.png
但是,从走势上来看,其Used Mono堆内存占用在5V5战斗结束后,并未完全回落到场景之前(如蓝框所示),这一点需要引起研发团队注意,确认其是否为部分指定容器缓存所致,从而排查项目是否存在堆内存泄露的隐患。

2、资源内存

经过统计,该游戏运行时的纹理资源数量峰值为1003个,内存占用峰值54.8MB。研发团队将纹理内存占用控制得很低,目前仅高于30%的行业项目。经过统计,在内存占用峰值处,ETC1和ETC2格式纹理占有835个,RGBA32格式纹理共占有89个,RGB24格式纹理占有5个,其余为RGBA16格式纹理。

纹理资源在项目运行期间的总体使用情况:

153924lui46uuizmgyzpkb.png
(2)控制网格顶点的数量

详细检测网格模型的顶点数(或面片数)使用是否过大。这是一个说起来容易但实施起来很难的问题,其难点在于如何定义一个Mesh网格的顶点数是否过大。在UWA测评报告中会有一个建议,即建议将Mesh网格顶点数控制在1500个以下。但实际上,这其实是一个“不科学”的规定,因为没有任何一个理论可以证明,其网格数量大于1500就是不合格,或则小于1500就一定合格。所以,我们这一年来花了大量的时间来寻求一种更为合理、科学的判断规则。我们认为判断一个网格模型使用是否合规并不应该是“静态”检测,而应该是一种“动态”检测,与上述纹理资源的检测一样,我们应该去看网格资源在底层渲染时到底占据了多少像素,从而以一种密度统计的方式来判断其网格使用量是否合理。因此,我们提出了一种网格模型测量标准,即“网格模型渲染密度”,其表示每单位数量(比如,1万)像素中,其网格模型的渲染顶点数量。

下图则为游戏运行过程中的网格模型渲染密度统计值。可以看出,虽然第一个模型“Mod_xyc_fz1001”的顶点数仅为1168,但其在游戏运行时平均每帧的渲染像素量仅为34.91个,也就是说平均每个像素要渲染33个网格顶点,这显然是一种浪费。因此,通过“渲染密度”这一检测方式,可以反映任何一个模型在游戏运行时的使用情况。在我们来看,这是一个比单纯设定1500更加合理的判断规则。

153926az4qpuft78uqj5v4.png
对于GameObject相关的资源管理,我们的建议如下:

(1)对项目中存在频繁Instantiate/Destroy操作的GameObject一定要进行大力彻查,下图即为某一项目的Instantiate实例化详情,我们建议对于红框处高频率和耗时的操作重点排查,因为其无论是CPU还是堆内存都对项目性能造成非常大的杀伤力!

153927sk8vxsts4szoko4k.png
(2)频繁的Active/Deactive操作不仅会造成CPU的浪费,同时,它还很可能间接造成更大的CPU耗时,比如Animator.Initialize耗时。在此,我们不妨看下另一款游戏的Animator.Initialize调用情况,如下图所示,其调用的频率和耗时较高,这就是频繁的Active/Deactive操作所造成的结果。因此,对于GameObject不必要的Active和Deactive操作进行控制,是非常有必要的。更为详细的资源加载性能优化总结,可参见《Unity移动游戏加载性能和内存管理全解析》。

153928ae1ee4qeveayb1gw.jpg
(3)不断检测、不断完善,优化是一个需要不断迭代、持之以恒的事情。下图则为《小米超神》经过几轮优化之后的资源管理变化情况。

153928f995us8i7qqiv7u0.jpg
以上则为《小米超神》游戏在CPU性能和内存管理方面的具体使用情况。优秀的CPU性能、非常少的堆内存分配以及引擎模块间的合理使用,足以看出该研发团队非常深厚的技术功底和对于引擎相当优秀的把控能力。

最后,非常感谢《小米超神》研发团队对 UWA 的认可和支持。感谢他们乐意将项目性能数据与大家一起分享,让更多的研发团队了解到一款性能优秀的MOBA手游在各个模块上应该做到怎样的程度。同时,也希望更多的开发团队可以与我们一起来分享他们的性能数据,让更多的游戏开发者受益!

锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛