技术分享连载(四十八)

技术分享连载(四十八)

本期话题:频繁GC是否能真正提升手游流畅度?如何优化UI中的动静元素?关于UI Panel重绘,你需要知道的一些Tips、动画文件定格位移不一致,如何切换?


精选5个性能优化问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。

UWA QQ群:793972859


动画

Q1:我有一个带位移动画A,有位置有旋转的变化,需要播完这个动画后切换到一个原地的动画B。现在我发现动画A没播放就会切换到B了,导致一些位移数据并没有作用到模型上,这种情况怎么处理?

0.png

Mecanim动画系统提供了“Apply Root Motion”功能来满足两个动画文件顶点位移不一致的切换的需求。当开启“Apply Root Motion”功能后,角色的GameObject位置会随着动画的更新而更新,因此,问题中的A切到B后,GameObject的位移将不会改变。建议该研发团队检测GameObject Animator组件的“Apply Root Motion”功能是否开启。


性能优化

Q2:关于GC优化,Unity官方文档中有如下两个推荐的方法,请问在手游上是否适用?(1)频繁GC,隔几秒主动调用一次,保证不需要的堆内存能够及时释放。适用于对内存总量较小的情况。(2)尽量避免GC,可以考虑先撑大内存。

上述两种方法在目前的移动游戏中并不适用。
(1)中频繁地调用GC是否会降低GC的CPU开销吗?理论上会,但实际上,即便是降低后的GC开销也会导致频繁的卡顿。下图为UWA上一款实际测评项目在红米Note2上频繁调用GC的开销。可以看到在红框处,其GC调用非常频繁,但是其CPU占用并没有因频繁调用而降低。
请输入图片描述
(2)中尽可能避免GC是非常推荐的,但撑大堆内存的方式是欠妥当的。最好的方式是通过降低不必要的堆内存分配来尽可能避免的GC的到来。UWA建议GC的调用频率应该在1000帧/次以上。具体的做法建议查看我们之前的技术推送:Unity内存的深度剖析
请输入图片描述


性能优化

Q:如下图所示,什么情况下会触发MaskableGraphic.Enable() ?现在我得到的结论是只要用到了Image组件,然后禁用启用带有这个组件的物体,都会触发进而产生GC。大家都怎么显示隐藏图片这种需求的,SetActive这种方式容易产生GC。
请输入图片描述
请输入图片描述

在UGUI中,Image组件并没有重写其父类的OnEnable函数,所以在激活时会出现MaskableGraphic.OnEnable。其中出现堆内存开销的话,通常是因为其父类函数Graphic.OnEnable中,UGUI在进行全局容器的Add等类似的操作时,遇到了扩容等产生堆内存的操作。

总之,在UGUI中,UI元素的激活和禁用所导致的堆内存分配,通常是不会持续出现的,其实不需要特别地处理。但对于其CPU开销,在UI元素数量较大时,依然是可观的,所以我们依然建议,对于激活禁用操作较为频繁的UI元素,可以尝试通过移出屏幕,缩放为0等方式来避免SetActive的调用。


UI 性能

Q:UWA建议“将较多的动态UI元素分组放在不同的UI Panel中”,那么请问如果是ScrollView里面多个item的话,是否意味着每个Item都加一个Panel会更好一些?

“动态元素”其实是相对的。在 ScrollView 中,一般情况下,如背包,其中的Item在滑动过程中是相对静止的,因此这种情况下只需要将这些Item放在一个UIPanel中即可。但在类似于聊天界面中,存在一些UI元素是有持续的动画的,那么就需要考虑对这类元素进行特殊处理,可以尝试将这部分有动画的UI放在独立的UIPanel中,或者在个数不多的情况下,各自变为一个UIPanel等。


UI 性能

Q:如果我在UIPanel下面放的是Sprite Renderer而不是NGUI的Sprite,是否会引起整个UIPanel的重绘?

在NGUI中使用Unity2D的Sprite有两种情况,一种是直接使用Unity2D的SpriteRenderer组件,这种情况下,NGUI和Unity2D之间是互不影响的,只是在深度的设置上相对会比较麻烦一些。另一种是使用NGUI的UI2DSprite组件,而该组件是NGUI对Unity2D的SpriteRenderer组件上进行封装的,方便使其深度与其他UI元素进行穿插,因此其行为和其他的UI元素一致,在某些情况下是有可能引起UIPanel的重绘。

今天的分享就到这里。也欢迎热爱进步的你加入UWA的QQ群(793972859),也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。 比起闭门造车,我们更乐意与大家各抒己见,畅所欲言;比起形而上的泛泛而谈,我们更乐意与大家直击痛点,对症下药。