PerformanceOptimization/TX工作室UI优化文档.md
- 当Canvas下的所有节点区域的最小AABB包围盒与Canvas的绘制区域有交汇时,才会进行DrawCall计算。[即便会进行DrawCall计算,也会有Canvas自身的2个DrawCall消耗]
- 当Canvas进行DrawCall计算时,即便把子元素移出至屏幕外,移出的子元素仍然参与DrawCall计算
- 移出屏幕外的子元素DrawCall计算规则与仍然在屏幕内的元素计算规则一致。因此如果移出屏幕外的元素有区域重叠,会使DrawCall增高。
- 当UI ModeifyMesh之后,就会触发Canvas的SendWillRendererCanvases,进行UI重绘。[RectTransform修改了SizeDetal、Anchor、pivot都会触发ModifyMesh,其他的SQT变化并不会触发ModifyMesh]
- 切换UI的Active之后,会触发ModifyMesh,会触发SendWillRendererCanvases消耗
- 切换UI的CanvasGroup或CanvasRenderer的alpha,不会触发ModifyMesh,也就是说设置alpha为0也能够达到SetActive=false的效果,并且alpha设置为0之后,也不会进行DrawCall计算
- 切换UI的Parent之后,也会触发ModifyMesh,会触发SendWillRendererCanvases消耗
- SetDeactive 最直接的方式。优点:无bug。 缺点 : 会造成SendWillRendererCanvaes
- 将UI节点移出屏幕外。 优点 :不会产生SendWillRenderCanvases 。 缺点 :移出出屏幕外同样会进行DrawCall计算。同时需要进行UI区域判断,不能造成UI重叠增加DrawCall。需要手动关闭Update函数。需要注意OnEnable与OnDisable的函数中逻辑是否能正常工作。如果Paent中有Layout,需要在移出屏幕的时候给UI添加IgnoreLayout
- 给UI添加CanvasGroup组件,Despawn的时候设置alpha为0。 优点: 不会造成SendWillRendererCanvaes,不会进行DrawCall计算。缺点 :如果Parent包含了Layout,仍然需要添加IgnorLayout。需要手动关闭Update函数。需要注意OnEnable与OnDisable的函数中逻辑是否能正常工作。需要注意CanvasGroup参数造成的其他逻辑因素。
- 切换Parent。优点:无 。 缺点 : 会造成SendWillRendererCanvaes。切换parent会造成其他消耗,比如重新设置SQT等变量。
- 测试数据: 66个Image
- 修改Iamge.Color ,Cpu消耗约 15ms,Gpu消耗 0.7ms
- 修改CanvasRender.color,Cpu消耗约 1.3ms,Gpu消耗 0.7ms
- 如果能够修改CanvasRender.color得到与修改Iamge.Color一样效果的,优先修改Canvasrender
- 无意义
- 测试数据: 66个Image
- 设置Active,Cpu消耗20ms
- 设置CanvasGroup,Cpu消耗 1.3ms。
- 重复设置Image的Color(相同Color),并不会引起Rebuild
- 重复设置Text的text(相同text),并不会引起Rebuild
- 重复设置Image的sprite(相同Sprite),并不会引起Rebuild
- 重复设置Image的fillAmount(相同数值,相差小于0.000001f),并不会引起Rebuild
UGUI的DrawCall分析过程应该分三种情况来讨论,不能一概而论。
首先这是最简单的情况,过程简述如下
出现Mask的情况较第一种非常复杂,不同的地方如下:
Canvas的情况就很好说明了
不使用Text的Best Fit
尽量避免Unity提供的Outline与Shadow
设置UGUI元素位置的时候,就算设置的位置和原位置一样,也会导致canvas重建,所以设置位置的时候最好有一定的判断
UGUI 和 NGUI 都有一个类来存储顶点uv颜色等信息,每一次重新绘制或者更改都会重新填充其中的数据
outline和tild image 长文本 最好不要是动态的 ,绘制消耗太大 。outline会复制5个原网格,定点数和边数增加5倍
其实原理很简单:对于每一个UI元素,对应其材质和shader找到一个batch,没有或者有但是被其他batch的UI挡住了就要新生成一个batch, 否则就合到已存在的batch。