https://hackmd.io/s/S1z1ByaGb#UGUI-%E6%B7%B1%E5%BA%A6%E5%84%AA%E5%8C%96%E6%8F%90%E5%8D%87%E6%89%8B%E9%81%8A%E6%95%88%E8%83%BD
- UI 基礎
- UI 優化工具
- UI-Canvas
- UI 控制項優化
- 其他
UI 基礎
術語
- Canvas or Canvases?
- dirty?
- Re-batch
- Sub-canvas
- Graphic : UI 的基礎類別
- Layout : UI 佈局,影響 UI 在畫布上的佈局
- The updates of Layout and Graphic components is called a rebuild
渲染細節
- Transparent 佇列
- Back-to-front with alpha blending
- tex2D
- High level of overdraw
- 填充率
Re-Batch
1. 保存結果,重用 Batching,直到 dirty
2. 任何組成網格發生變化
3. 如何計算 Batching
I. 網格排序
a. 深度
b. 檢查覆蓋關係
c. 材質
II. 多執行緒
Re-build
- Layout rebuilds
- Graphic rebuilds
- PerformUpdate() :: CanvasUpdateRegistry invoked by WillRenderCanvases 事件
a. Dirty Layout
b. Clipping components (such as Masks)
c. Dirty Graphic components
Layout rebuilds
- UI 元素的位置、大小發生改變
- 優先計算靠近 root 節點
- 根據層級深度、排序
Graphic rebuilds
- 頂點數據 has been marked as dirty the mesh is rebuilt
- 材質或貼圖資料 has been marked as dirty
the attached Canvas Renderer’s material will be updated
UI 優化工具
- Unity Profiler
- Unity Frame Debugger
- Xcode’s Instruments or Intel Vtune
- Xcode’s Frame Debugger or Intel GPA
Unity Profiler
- Canvas.BuildBatch:計算 Canvas Batch 過程
- Canvas.SendWillRenderCanvases
a. 包括部分 C# scripts 調用的消耗。例 willRenderCanvases
b. Dirty UI components will update their
Unity Frame Debugger
Screen Space - Overlay:Canvas.RenderOverlays group
Screen Space - Camera:Camera.Render group
World Space:Render.TransparentGeometry group
UI-Canvas
UI Canvas 重建
a. 子物件次序
b. 多級 Canvas
c. 一般準則
d. 輸入和射線(Raycasting)
e. 射線(Raycast)優化
UI Canvas 重建
- 生成 UI 組件,包括 Layout,字體多邊形
- Batch
- 重建會是性能貧頸嗎?
a. 同一個 Canvas 包含了大量的 UI 元素,需要計算 batch,排序等
b. 某個或某些 Canvas 太過平凡的 dirty
子物件次序
- 影響 batch 的結果
- 避免出現中間層
多級 Canvas
- 同級 Canvases
- Sub-Canvases
- 不會跨越 Canvas 進行合批
- 最少的重建消耗,最少的 DrawCall 消耗
一般準則
- 一個 Canvas
包含所有靜態和不會改變的 UI 組件 - 另一個 Canvases
存放所有動態 UI 組件
如果動態 UI 元件數量較大,可以繼續細分
輸入和射線(碰撞檢測)
- Graphic Raycaster 處理輸入
- 每個 Canvas 綁定 Graphic Raycaster,每幀檢測滑鼠的位置
- 5.4 之後的版本更加優化
- 開發者可以訂製 InputManager
射線(Raycast)優化
- 必要的 UI 組件才開啟 Raycast Target
- 開啟 Raycast Target 的 UI 元件越少,層級越淺,性能越好
- 對於複雜的控制項,盡量在根節點開啟 Raycast Target
- OverrideSorting 屬性會打斷射線,可以降低層級遍歷的層本
UI 控制項優化
- UI 字體
- 滾動視圖
UI字體
- 字體網格重建
- 動態字體和字體集
- 後備字體和記憶體
- Best Fit 和效能
- 每個字體都是獨立的四邊形
- 預留足夠的空間,避免字體出框
- 避免因字體打斷批次處理
字體網格重建
- UI Text 組件發生變化
- 父物件發生變化
- Disable 和 Re-enabled UI Text 或父物件
Enable/Disable 包含大量 UI 元件的組件,會導致掉幀
動態字體和字體集
- 運行時,根據 UI Text 元件的內容,動態生成字體圖集
- 不同的字體庫維護不同的 texture 圖集
- 字型的 size、大小寫等,都會保存不同的字型在字體集中
- 當前 Front texture 不包含 UI Text 需要顯示的字體時,當前 Font texture 需要重建
- 如果當前 Font 圖集太小,系統將嘗試重建,並加入需要使用的字型
- 如何重建字體圖集
a. 第一步,使用當前 Font 圖集的大小,並且只包含有效 UI Text 元件的字型,如果成功則結束
b. 如果當前 Font 圖集大小不滿足需求,則擴展 Font 圖集大小 - 圖集的大小只增不減
- Font.RequestCharactersInTexture 可以有效降低啟動時間
- Font 圖集重建時ㄝ只會保存當前 active UI Text component
備用字體和記憶體
- 備用字體都會被載入到記憶體
- 如果字體庫特別大,記憶體會有很大的壓力
- 字體庫裁剪
Best Fit and performance
- 自我調整到最大的整數大小
- Font 圖集壓力較大
- 一般不建議開啟
滾動視圖
- 列出所有需要顯示的 UI 組件
a. 產生實體大量的 UI
b. 重建滾動視圖
c. 只適用於少量 UI 元件的情況 - 緩存(池)所有元件
a. 適用於複雜的 UI 系統
b. 需要申請足夠大的記憶體
c. 添加 RectMask2D 元件,可以提升性能
其他
- Layout 組件很昂貴
- Disable Canvas Component
- 避免 UI 組件重疊
- 優化 UI Shader,移除多餘的特性
Unity UI Profiling Tools :
https://unity3d.com/learn/tutorials/temas/best-practices/unity-ui-profiling-tools