想到啥寫啥吧,就隨筆類似記錄知識點一樣一個個說,有空的話再編輯或者再開新帖具體講講某些點,都是UGUI優化的建議
(1)優化填充率,裁減掉無用的區域,鏤空等。
(2)Mask的使用以及選擇,或者用自用Mask,這塊原理我在UGUI的合批里講過,可以翻一翻我前面博客這里不再復述。
(3)少用unity自帶的outline和shadow,會大量增加頂點和面數,比如outline,他實現原理是復制了四份文本然后做不同角度的便宜,模擬描邊,要不就用自己實現的(挖坑待填)。
(4)操作全屏UI時建議將場景相機移走或者關閉,降低渲染面數,因為就算是被全屏UI遮擋住了,實際上后面的場景還是被渲染的占用資源。
(5)如果非特殊需求沒必要使用CanvasPixedPerfect,因為比如在scrollView時,滑動視圖時一直會導致不斷重繪產生性能損耗。
(6)不需要接受點擊時間的物件將RayCastTarget關掉減少事件響應,從底層看是因為UGUI的RayCastTarget的響應是從數組中遍歷檢測是否和用戶的點擊區域響應,所以能夠縮減數組大小自然能夠縮減遍歷次數。
(7)UI動靜分離,因為如果了解過Unity的UGUI源碼就能發現Batch building 的過程,Canvas 會將其 ui 元素生成的 mesh 組合並生成合適的繪制命令給 Unity 渲染系統。並且過程的結果會被緩存並重用,直到 Canvas 重新被標記為臟。這會在組合的網格發生變化時發生。Canvas 會根據子節點里帶有 Canvas Renderer 組件的 ui 來生成 網格,但是不包括 Sub-Canvas 的子節點,也就是說每個 Canvas 單獨負責自身的 Batch building。Batch building 的過程會對根據深度、重疊測試、材質等對各個 Mesh 進行排序、分組、合並,這個過程是多線程的,在移動端(核心少)與桌面端(核心多)會呈現相當大的差異。Canvas下的某個元素進行變化時都會導致同一個Canvas下的所有元素都進行網格重建,這樣會導致某些靜態部分的網格被不同重繪導致額外性能損耗。而常用的拆分canvas有兩種,一種是在同一個根節點下new一個動態Canvas,類似圖示:
這種用法的缺點是層級關系不好調控,當靜態Canvas下的某些物體需要顯示在動態canvas下的物件上時就很麻煩。
所以我推薦第二種方式子Canvas的方式來實現這點。
類似上圖在子物體上掛在subCanvas,這樣的好處是它與其父節點是隔離的,Sub-Canvas 的 rebuild 不會逼迫父節點重建幾何,反之亦然,不過還是存在一些邊界情況。比如父節點變化導致子節點大小變化。但是Canvas會打斷合批,所以比如只是拖拽某個組件的操作,可以在開始拖動時掛載subcanvas,結束拖動移除canvas,這樣的做法能夠保證物體的合批順序,同時兼顧了動靜分離。
(7)對於UI上常用的改變顏色的操作,不要使用Image組件上的Color屬性改變顏色,這樣會導致整個Canvas的重建,可以新建個材質,設置材質給Image的Material通過修改材質的顏色來達到同樣效果
(8)對於界面上常用的組件隱藏,別使用SetActive來控制顯影,有兩種方式,一種是通過設置物體上的CullTransparentMesh並且控制物體透明度進行剔除,這個一般用於單個ui,如果是多個UI要不顯示的話通過設置canvasGroups的Alpha控制顯影。
(9)Text的組件的BestFit非必要別開,因為這樣開啟這個會不斷生成各種尺寸的字號字體圖集,增加不必要開銷。
下節寫個具體的案例,這個也是很多人沒注意並且可能都沒發現的誤區: