UGUI 优化及原理

UGUI 优化及原理

整理自:https://v.qq.com/x/page/e0520qxtjox.html 《UWA直播第四弹:Unity UI 模块优化案例精讲》

动态元素

  • 少用Outline, Tiled Sprite(会有很多顶点数)
  • 减少动态长文本

元素更新方式:

Canvas.SendWillRenderCanvas

  • 处理两个队列
  • m_LayoutRebuildQueue 记录layout发生变化的元素
  • m_GraphicRebuildQueue 记录graphic发生变化的元素

缓存

  • scale = 0 或 Alpha Group = 0 无顶点重建开销
  • 不要使用color.a = 0 这样不会减少drawcall

DrawCall合并规则

渲染顺序

  • 重叠检测
  • 分层合并

    image

    如图所示,需要减少不同图集的穿插 否则不会合并

    UI制作注意点:

    • 不规则图形摆放

      看似未重叠其实可能重叠了导致无法合并

    • UI元素的旋转

      覆盖区域会变大

    • 动态遮挡

      需要改变hierarchy中的排序来达到效果 否则会被之前/之后的UI覆盖

    • 3DUI

      因为旋转、投影到2D平面,很容易发生重叠 造成drawcall上升

      image

网格更新机制

Canvas.BuildBatch 更新所有DrawCall

  • WaitingForJob
  • PutGeometryJobFence
    上面两个若是出现 都是子线程里网格开销过大所导致的
  • BatchRender.Flush *
    开了多线程渲染后,等待网格合并就会在主线程中出现这个 特别是半透明过多

    如果要查看UI性能开销,先关闭多线程渲染,优化到合理的情况下,WaitingForJob和PutGeometryJobFence都会消失,只留下Canvas.BuildBatch

​ 对UGUI来说,重叠的几个UI会合成一个Mesh,几个submeshes。所以在一个元素发生变化的时候,整个canvas会重新进行网格合并,开销会很大。

所以拆分Canvas很重要!!!

降低界面的渲染开销

渲染开销的一些指标

  • Profilling
  • DrawCall
  • Mesh.CreateVBO
  • Overdraw

drawCall : (drawcall与开销的关系:线性)

  • 指标
    • 红米2:200个静态 -> 8ms 目标值:30
    • 红米Note2: 200 -> 5.1ms
    • Z值!=0
    • 屏幕外元素
    • 未”隐藏”元素(Color.a = 0)
    • Hierarchy穿插、重叠
    • 图集分离(虽然Tag打到了一起,但是压缩格式不一样,就会到不同的Group里去)

降低界面的更新开销

  • 动静分离
  • 降低更新频率
    比如小地图,每隔一段时间更新UI位置
  • 避免”敏感”操作
    不要每帧更新localposition,即使前后位置一样,也会引发更新
  • 优化选项