作者:@qingqing-zhao
本文為作者原創(chuàng)澜薄,轉(zhuǎn)載請注明出處:https://www.cnblogs.com/zhaoqingqing/archive/2018/09/25/9658403.htmlhttps://www.cnblogs.com/zhaoqingqing/p/9658403.html
可以通過Frame debugger查看每個(gè)drawcall繪制了哪些東西
UGUI源碼下載地址:https://bitbucket.org/Unity-Technologies/ui/downloads/
本文測試環(huán)境:unity2018.2.9f1茅信,基于Unity Editor (PC平臺)
合批的過程
網(wǎng)格更新機(jī)制
-
Cavans.SendWillRenderCanvas
- m_LayoutRebuildQueue
- m_GraphicRebuildQueue
-
Canvas.BuildBatch 更新所有DrawCall
- WaitingForJob 子線程網(wǎng)格合并
- PutGeometryJobFence
- BatchRendere.Flush UI如果開多線程渲染,BatChRender.Flush會增高弦悉,主線程在等待子線程的結(jié)果時(shí)Flush會等待。
哪些因素的改變會引起合批
從源碼中可以看到倍靡,這些數(shù)據(jù)的改變會引起合批
源碼地址: UI / UnityEngine.UI / UI / Core / Utility / VertexHelper.cs
private List<Vector3> m_Positions = ListPool<Vector3>.Get();//頂點(diǎn)位置的拷貝或指定新頂點(diǎn)位置的數(shù)組
private List<Color32> m_Colors = ListPool<Color32>.Get();//顏色
private List<Vector2> m_Uv0S = ListPool<Vector2>.Get();//基本紋理坐標(biāo)
private List<Vector2> m_Uv1S = ListPool<Vector2>.Get();//第二套紋理坐標(biāo)
private List<Vector2> m_Uv2S = ListPool<Vector2>.Get();//第三套紋理坐標(biāo)
private List<Vector2> m_Uv3S = ListPool<Vector2>.Get();
private List<Vector3> m_Normals = ListPool<Vector3>.Get();//法線
private List<Vector4> m_Tangents = ListPool<Vector4>.Get();//切線
private List<int> m_Indices = ListPool<int>.Get();//mesh的索引
Mesh的API:http://wiki.ceeger.com/script/unityengine/classes/mesh/mesh
http://wiki.ceeger.com/script/unityengine/classes/mesh/mesh.getindices
怎么避免合批
盡量減少“動(dòng)態(tài)”長文本(運(yùn)行時(shí)修改文本內(nèi)容)
Image或Text碉京,如果不需要點(diǎn)擊厢汹,則不要勾選Raycasts
降低界面的更新頻率
避免圖集分離,使用相同的圖集谐宙。
同一圖集的Image元素應(yīng)盡量保證在Hierarchy中連續(xù)烫葬,避免中間插入其他圖集,或插入文本卧惜。
避免圖片疊加在一起(遮擋厘灼,旋轉(zhuǎn))
如果sprite是中心鏤空且切圖為九宮格時(shí),可以去除fill center咽瓷,以減少over draw
透明Image设凹,用來做響應(yīng)點(diǎn)擊事件,同樣存在開銷
避免或減少M(fèi)ask的使用茅姜,1個(gè)Mask至少增加兩個(gè)DC
避免頻繁刪除/增加UI對象闪朱,UI層次結(jié)構(gòu)變化會引起Canvas的更新
避免頻繁動(dòng)態(tài)的更新UI元素的Vertex, Rect, Color, Material, Texture等,可能引起Canvas數(shù)據(jù)更新和Batch更新計(jì)算钻洒,有可能引起VBO Update(重新提交頂點(diǎn)數(shù)據(jù))奋姿。
盡可能使用少的UI Material和貼圖(使用圖集),使得可以Batching素标。
同一父節(jié)點(diǎn)下所有子節(jié)點(diǎn)称诗,保持相同的層次結(jié)構(gòu)(如List控件下的item),便于底層相同depth下UI元素Batch头遭。
避免UI元素?cái)?shù)目過多和層次結(jié)構(gòu)過于復(fù)雜影響B(tài)atch更新速度寓免。
固定的Text考慮與背景圖層合在一張圖上(可能不便本地化,但可以減少drawcall)计维。
使用緩存池袜香,對緩存頻繁使用的元素。
部分內(nèi)容參考:http://gad.qq.com/article/detail/25947
HUD處理(動(dòng)靜分離)
Canvas重建就是為了合并DC鲫惶,將經(jīng)常變化的文字放在獨(dú)立的Canvas蜈首,手動(dòng)分離Canvas(會增加DC,不能和其它文字合并)欠母,但文字變化時(shí)其它Canvas就不需要重建欢策。
示例:名字和血條分開在兩個(gè)不同的節(jié)點(diǎn)下。這樣當(dāng)血條變化時(shí)赏淌,就不會引起名字的更新猬腰。如下圖所示:
2、設(shè)置scale為0猜敢,而不是設(shè)置active = false/true姑荷,或者添加Alpha Group,設(shè)置alpha=0/1
不勾選FillCenter
鏤空九宮格不勾選FillCenter缩擂,在Scene的Overdraw下可以查看到鼠冕,不勾選FillCenter,overdraw會減少胯盯。
少用Effect功能
少用Outline懈费,Tiled Sprite
outline額外生成7倍頂點(diǎn)
在一個(gè)空場景中,給Text添加outline之后博脑,頂點(diǎn)數(shù)大約是未添加之前的7.5倍憎乙。
去掉outline之后票罐,頂點(diǎn)數(shù)下降了很多。
Image不使用Tiled
type=simple時(shí)的頂點(diǎn)數(shù)
使用Tiled之后泞边,頂點(diǎn)數(shù)也上漲很多该押。
參考資料
Unity官方論壇發(fā)布 Unity UI性能優(yōu)化技巧
工具:UI層級輔助工具,用于顯示UI的層級阵谚、批次等數(shù)據(jù)蚕礼,便于UI性能優(yōu)化。使用者可以結(jié)合以上規(guī)則梢什,分析當(dāng)前UI元素排列順序奠蹬、材質(zhì)貼圖設(shè)置,優(yōu)化UI Batching嗡午,減少UI Drawcall囤躁。