技术分享连载(三十三)

技术分享连载(三十三)

本期话题:UI图集更新、Setpass Call和Draw Call...精选5个性能优化问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。

【技术分享】是UWA推出的技术交流栏目,我们会定期将开发团队中反馈的常见问题加以总结并梳理在此,以供大家参考。

UWA 问答社区:answer.uwa4d.com
UWA QQ群:793972859


资源管理

Q1:在Unity 5.x版本下,我们在用UGUI的过程中发现它把图集都打进了包里,这样就不能自动更新了,请问图集怎么做自动更新呢?

在Unity 5.x中UGUI使用的Atlas确实是不可见的,因此无法直接将其独立打包。但我们建议,可以把Packing Tag相同的源纹理文件,打到同一个AssetBundle中(设置一样的AssetBundle Name),从而避免Atlas的冗余。同时这样打包可以让依赖它的Canvas的打包更加自由,即不需要把依赖它的Canvas都打在一个AssetBundle中,在更新时直接更新Atlas所在的AssetBundle即可。


资源管理

Q2:图中的Material.SetPassFast占用很高,这是我在第一次实例化一个特效,但是第二次实例化就不会出现高值了,请问能怎么优化吗?

请输入图片描述

该过程是在处理Shader,Unity 5.3以后在第一次显示时才会将Shader进行Warmup,所以就会造成一次峰值卡顿。研发团队可以参考我们之前的分享:Unity加载模块深度解析之Shader篇以加深理解。


资源管理

Q3: UWA建议“尽可能将静态UI元素和频繁变化的动态UI元素分开,存放于不同的Panel下。同时,对于不同频率的动态元素也建议存放于不同的Panel中。”那么请问,如果把特效放在Panel里面,需要把特效拆到动态的里面吗?

通常特效是指粒子系统,而粒子系统的渲染和UI是独立的,仅能通过Render Order来改变两者的渲染顺序,而粒子系统的变化并不会引起UI部分的重建,因此特效的放置并没有特殊的要求。


性能优化

Q4:Draw Call和Setpass Call,这两个指标主要是看哪一个?关于这点众说纷纭,很多地方都是说看SetPass Call,但是在UWA的性能测试中,还是把Draw Call当成唯一指标。

请输入图片描述

在 Unity 5.x 中,SetPass Call与 Draw Call相比,SetPass Call的指标与性能相关性更大(比如Static Batching的开启不影响Draw Call数,而SetPass Call通常会明显下降)。但 SetPass Call在某些情况下也同样存在问题,比如往一个场景中添加任意个相邻且材质相同的大网格物体(使Dynamic Batching失效)时,SetPass Call并不会变化。因此在UWA中,我们所使用的是类似Profiler 中 Total Batches 这一项指标,通常该数值与 Frame Debugger 中的数值基本一致,因此可以通过该工具来查看每个Batch的内容,从而更有针对性地进行优化。


性能优化

Q5:我看到UICamera.Update()的GC调用特别高,只要我一移动就会产生2.8K的GC,看起来是NGUITools.FindInParents这个方法导致的,有没有什么可以优化的方法呢?
请输入图片描述
请输入图片描述

在 Editor 下,当调用GetComponent() 且 T组件并不在当前的GameObject 上时,确实会出现GC Alloc,但这在发布后是不会出现的,因此建议在真机上做一个验证。这是因为在Editor下,Unity的MissingComponentException实现所致,在出现以上情况时,Unity 并不是直接返回一个 NULL,而是返回一个代理 Object用来储存一些相关信息,在后续被访问时可以给出更详细的报错信息。

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