UGUI 深度優化提升手遊效能

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 基礎

術語

  1. Canvas or Canvases?
  2. dirty?
  3. Re-batch
  4. Sub-canvas
  5. Graphic : UI 的基礎類別
  6. Layout : UI 佈局,影響 UI 在畫布上的佈局
  7. The updates of Layout and Graphic components is called a rebuild

渲染細節

  1. Transparent 佇列
  2. Back-to-front with alpha blending
  3. tex2D
  4. High level of overdraw
  5. 填充率

Re-Batch

1. 保存結果,重用 Batching,直到 dirty
2. 任何組成網格發生變化
3. 如何計算 Batching
  I. 網格排序
     a. 深度
     b. 檢查覆蓋關係
     c. 材質
  II. 多執行緒

Re-build

  1. Layout rebuilds
  2. Graphic rebuilds
  3. PerformUpdate() :: CanvasUpdateRegistry invoked by WillRenderCanvases 事件
    a. Dirty Layout
    b. Clipping components (such as Masks)
    c. Dirty Graphic components

Layout rebuilds

  1. UI 元素的位置、大小發生改變
  2. 優先計算靠近 root 節點
  3. 根據層級深度、排序

Graphic rebuilds

  1. 頂點數據 has been marked as dirty the mesh is rebuilt
  2. 材質或貼圖資料 has been marked as dirty
    the attached Canvas Renderer’s material will be updated

UI 優化工具

  1. Unity Profiler
  2. Unity Frame Debugger
  3. Xcode’s Instruments or Intel Vtune
  4. Xcode’s Frame Debugger or Intel GPA

Unity Profiler

  1. Canvas.BuildBatch:計算 Canvas Batch 過程
  2. 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 重建

  1. 生成 UI 組件,包括 Layout,字體多邊形
  2. Batch
  3. 重建會是性能貧頸嗎?
    a. 同一個 Canvas 包含了大量的 UI 元素,需要計算 batch,排序等
    b. 某個或某些 Canvas 太過平凡的 dirty

子物件次序

  1. 影響 batch 的結果
  2. 避免出現中間層

多級 Canvas

  1. 同級 Canvases
  2. Sub-Canvases
  3. 不會跨越 Canvas 進行合批
  4. 最少的重建消耗,最少的 DrawCall 消耗

一般準則

  1. 一個 Canvas
    包含所有靜態和不會改變的 UI 組件
  2. 另一個 Canvases
    存放所有動態 UI 組件
    如果動態 UI 元件數量較大,可以繼續細分

輸入和射線(碰撞檢測)

  1. Graphic Raycaster 處理輸入
  2. 每個 Canvas 綁定 Graphic Raycaster,每幀檢測滑鼠的位置
  3. 5.4 之後的版本更加優化
  4. 開發者可以訂製 InputManager

射線(Raycast)優化

  1. 必要的 UI 組件才開啟 Raycast Target
  2. 開啟 Raycast Target 的 UI 元件越少,層級越淺,性能越好
  3. 對於複雜的控制項,盡量在根節點開啟 Raycast Target
  4. OverrideSorting 屬性會打斷射線,可以降低層級遍歷的層本

UI 控制項優化

  1. UI 字體
  2. 滾動視圖

UI字體

  1. 字體網格重建
  2. 動態字體和字體集
  3. 後備字體和記憶體
  4. Best Fit 和效能
  5. 每個字體都是獨立的四邊形
  6. 預留足夠的空間,避免字體出框
  7. 避免因字體打斷批次處理

字體網格重建

  1. UI Text 組件發生變化
  2. 父物件發生變化
  3. Disable 和 Re-enabled UI Text 或父物件

Enable/Disable 包含大量 UI 元件的組件,會導致掉幀

動態字體和字體集

  1. 運行時,根據 UI Text 元件的內容,動態生成字體圖集
  2. 不同的字體庫維護不同的 texture 圖集
  3. 字型的 size、大小寫等,都會保存不同的字型在字體集中
  4. 當前 Front texture 不包含 UI Text 需要顯示的字體時,當前 Font texture 需要重建
  5. 如果當前 Font 圖集太小,系統將嘗試重建,並加入需要使用的字型
  6. 如何重建字體圖集
    a. 第一步,使用當前 Font 圖集的大小,並且只包含有效 UI Text 元件的字型,如果成功則結束
    b. 如果當前 Font 圖集大小不滿足需求,則擴展 Font 圖集大小
  7. 圖集的大小只增不減
  8. Font.RequestCharactersInTexture 可以有效降低啟動時間
  9. Font 圖集重建時ㄝ只會保存當前 active UI Text component

備用字體和記憶體

  1. 備用字體都會被載入到記憶體
  2. 如果字體庫特別大,記憶體會有很大的壓力
  3. 字體庫裁剪

Best Fit and performance

  1. 自我調整到最大的整數大小
  2. Font 圖集壓力較大
  3. 一般不建議開啟

滾動視圖

  1. 列出所有需要顯示的 UI 組件
    a. 產生實體大量的 UI
    b. 重建滾動視圖
    c. 只適用於少量 UI 元件的情況
  2. 緩存(池)所有元件
    a. 適用於複雜的 UI 系統
    b. 需要申請足夠大的記憶體
    c. 添加 RectMask2D 元件,可以提升性能

其他

  1. Layout 組件很昂貴
  2. Disable Canvas Component
  3. 避免 UI 組件重疊
  4. 優化 UI Shader,移除多餘的特性

Unity UI Profiling Tools :
https://unity3d.com/learn/tutorials/temas/best-practices/unity-ui-profiling-tools

原文地址:https://www.cnblogs.com/nafio/p/9970439.html