1.如果a, b, c三个sprite,a和b是用的一个纹理或是图集,c用的另一个纹理或是图集,a , b渲染完再渲染c drawcall是2,如果a, c, b的顺序渲染就是3,所以相同纹理或是图集的sprite在Hierarchy中最好连续。(元素z要等于0!!)
2.透明image,大多是作为点击事件的响应媒介,也会造成开销。
3.非透明的九宫格图片,如果中心是透明的,可以去除fill center,以减少over draw。
4.前景后景
5.不规则形状元素重叠,不会合并drawcall。
6.旋转,原理和上面相似,旋转会导致不必要的重叠。
7.动态元素少用Outline和Tiled Sprite,会增加顶点数,少用动态(缩放、颜色等)长文本,字数太多,动态更新耗时。
8.3D UI旋转会导致drawcall骤增。
(目标drawcall 30以下)
元素更新方式:
Canvas.SendWillRenderCanvas 渲染前处理下面两个队列的元素,静态UI元素不进入队列不会轮询,开销几乎没有(NGUI每帧所有元素都要轮询)
-队列
-m_LayoutRebuildQueue
_m_GraphicRebuildQueue
动态元素处理,比如HUD(血条、伤害数字)会缓存
UGUI可以Scale = 0 (减少顶点数), Alpha Group = 0,不要SetActive(false),不要用Alpha = 0 (draw call和overdraw不会优化)。 NGUI相反 Alpha减顶点数,Scale不减少。(处理动态UGUI优势明显,NGUI会产生大量堆内存)
网格更新机制
Canvas.BuildBatch更新所有drawcall(5.2之后默认走子线程)
-waitingForJob (子线程网格合并开销太高)
-PutGeometryJobFence (子线程网格合并开销太高)
-BatchRenderer.Flush (开多线程渲染后,上面两个会消失,这个开销会高,主线程在等,特别半透明渲染)
优化策略,关闭多线程渲染,减少前两个开销,再开多线程
UGUI以Canvas为单位更新,可以拆分Canvas,大的Canvas只要有元素更新就会全更新,导致上面前两个函数开销高。(策略动静分离)
位置赋值时设置一个阈值,不然就算位置不变,网格也会更新。
调试工具:Frame Debugger(NGUI调试drawcall时比较透明,UGUI做的并不好很难确定)
视频讲解 https://blog.uwa4d.com/archives/1875.html