1. 程式人生 > 其它 >UGUI優化(轉)

UGUI優化(轉)

原文地址:UGUI進階知識[十]UGUI優化知識點和一些底層特性_張家二歌的部落格-CSDN部落格

UGUI元件繪製原理

UGUI的UI分為兩類:Layout(佈局,繼承自LayoutGroup)和Graphics(顯示,繼承自Graphics)。Graphic類繼承自ICanvasElement介面,這個介面限制了繼承自其的子類的指令碼所掛的物體必須作為掛載了Canvas元件的物體的子物體,下文要說到的關於顯示類UI重建的方法宣告在ICanvasElement接口裡面,方法名字叫做Rebuild。

Graphic類有個比較重要的自類MaskableGraphic。其繼承自IMaskable介面,繼承自這個介面的子類能夠被Mask元件的剔出效果影響。

Rebatch:Canvas收集所有子物體的CanvasRenderer元件的渲染繪製資訊,並對其進行批處理和合並。

Canvas.WillRenderCanvases這個函式是canvas的一個代理,每一幀準備進行繪製的時候會呼叫,在profilter中可以看到,如果佔用過高說明canvas的某個/某些UI介面元素的重建開銷較大,可以通過動靜分離UI來優化。

CanvasUpdateRegistry:這個類儲存了更新的佇列,所有下一幀需要被rebuild的UI都會加入這個佇列中,這些UI包括顯示型別的UI和排序型別的UI.PerformUpdate是Canvas的WillRenderCanvases代理的註冊函式,在這裡執行每個UI的rebuild方法和mask的裁剪操作。

對於一些自動排序的元件來說,他們繼承的基類LayoutGroup會使用到用於重排序的類,名字叫做LayoutRebuilder.其下的重要方法是MarkLayoutRootForRebuild,這個方法對需要重繪的排序UI註冊進CanvasUpdateRegistry的更新佇列,所有能被排序的類都繼承自ILayoutElement。

顯示型別的UI元件,繼承自Graphic類,生成頂點和三角面的時候會呼叫重寫自Graphic的OnPopulateMesh(VertexHelper toFill)方法,這個方法傳入的VertexHelper引數用來收集繪製所需的頂點和三角面。

UGUI的兩種Mask

RectMask2D只能以其所在的物體的Recttransform的矩形區域為邊界進行剪下,子物體超出其 RectMask2D的邊界部分的頂點直接捨棄掉。

Mask元件使用到了shader裡面的模板緩衝(StencilBuffer)的原理。

優化策略

Overdraw:畫素在一幀裡被繪製多少次,理論上一次是最優的(沒有遮擋關係),可以在檢視。

重建:在UGUI中,一般沒有更改的元件不會每幀都進行重新計算並繪製,而是每幀繪製的時候使用的是上一次計算好後快取的計算資料。

對於顯示型別的元件來說UGUI機制裡面有個名詞叫做髒標記(Dirty),表示元件有了顯示上的更改需要被重新計算並繪製,設定成髒標記的UI元件將在下一幀執行完批處理的時候被重新計算並繪製,一個元件如果被更改之後沒有設定成髒標記,則其繪製使用的依然是上一次計算的資料,所以樣子沒有改變。髒標記包括頂點髒標記,材質髒標記(在更換材質的時候標記,只改material引數不標記),佈局髒標記。

在OnEnable呼叫的時候,上述程式碼的SetAllDirty方法會被執行,也就是說當禁用或者啟用某個顯示型別的UI元件或者元件所在的物體的時候,它都會被重建一次。

優化

1.降低overdraw

像邊框這類的圖片可以用UnitySpriteEditor的九宮格去掉中間的畫素

UGUI射線點選的判斷過程用的是recttransform矩形區域而不是網格頂點,基於此那些不需要顯示的(透明度為0)的btn可以去掉頂點資訊。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TransparentImage : Image
{
protected override void OnPopulateMesh(VertexHelper toFill)
{
toFill.Clear();
}
}

2.降低batch

在使用多個mask的時候可以使用mask元件,使用一個mask的時候可以考慮rectmask2d

在擺放UI或者生成UI的時候,儘量考慮是否符合UGUI合批規則,儘量多的減少UI的drawcall,可以通過改變Hierarchy層級,考慮更改覆蓋關係,儘量使用相同材質,相同texture的手段。

同一層的image打成一個圖集,可以合批。

3.降低重建

對於更改會設定髒標記的UI的屬性,儘量考慮採用不會引起髒標記的方法進行設定,例如更改image顏色的時候,不採取直接更改Image的color屬性,而是設定一個材質,更改shader的顏色。

UI動靜分離,或者在常發生重建的UI上加canvas。

減少使用setactive,用CanvasRenderer元件的Cull Transparent Mesh代替,如果要控制一個物體以及其所有子物體的顯隱,可以臨時給這個物體新增Canvas Group元件,通過CanvasGroup的alpha值來控制顯隱。