前言
在遊戲項目中,製作UI界面,是大部分客戶端工程師需要做的一項工作。一般的工作流是,工程師捋清策劃的需求點,拼UI、寫邏輯代碼,修復邏輯bug,讓遊戲能正常運行起來,好像工作就到此完成了。但這樣的工作流其實是不完備的,整個流程中缺少了對性能的考慮,更好的習慣是,工程師從一開始著手工作時,就將任務拆分為實現功能和性能分析兩個子任務。將優化提前到一開始投入生產的階段,減少後期返工優化。
性能分析檢查點大致總結為:
1、合理設置UI元素的層級,減少DrawCall合併的打斷
2、分析界面操作,動靜分離,根據操作引起的變化,對界面元素進行適當分組拆分panel
1、根據UI界面出現頻次,確定載入和卸載策略
2、確定界面內UI元素是否需要延遲或分幀載入,比如大貼圖、粒子特效、大量元素載入
3、分析界面操作,對操作所需數據進行適當的前置緩存
1、利用Scene視圖中的OverDraw模式檢查界面OverDraw
本文將結合以上檢查點,介紹筆者使用NGUI製作UI的相關優化實踐。
這篇文章適合的讀者:
對於NGUI製作UI界面感興趣,或者正在開展相關工作。該文章會介紹一些最佳實踐,可以在實際工作中作為參考。
DrawCall方面
理解DrawCall,首先應該知道,在Unity中,每次CPU準備數據並通知GPU繪製的過程稱為一次Draw Call。當我們談DrawCall優化時,是為了減少CPU在調用圖形介面上的開銷,因為每一次的調用CPU都需要做很多工作。Widget是NGUI中負責界面顯示的基礎單位,並由Widget繼承出許多UI元素,每個Widget都必從屬於一個Panel。在NGUI下,統一使用Depth來進行渲染順序的控制,Panel之間會基於Panel的Depth進行一次排序,Panel內部也會基於Widget的Depth進行一次排序。NGUI的實際渲染流程,就是把Widget組件生成的緩存,做成UIDrawCall之後,生成mesh來渲染的過程。
優化Drawcall主要的目的是儘可能的合併指令或者讓更新時只更新必要的變化,以此降低CPU的負擔。
降低界面的渲染開銷
降低界面的渲染開銷,也就是界面的整體DrawCall,能合併的就合併。做到:
一、盡量少穿插使用不同圖集,減少DrawCall合併的打斷。因為圖集將密切相關的圖打到一起,使用同一個材質,使得存在DrawCall合併的可能,但如果沒有控制好渲染順序,依然達不到好的優化效果。
二,UITexture盡量只在大圖的情況下用,能用圖集就是用圖集。三、不同的字體都使用一個Depth,並且這個Depth最好不要與圖片Sprite有交叉,最好放在最上層。
具體的檢查操作是,結合NGUI Panel Tool工具和NGUI DrawCallTool工具,通過PanelTool找到高DrawCall的界面,再打開NGUI DrawCallTool工具,選定指定的Panel, 查看間隔的DrawCall是否使用了相同的材質球, 再查看具體的widgets,是否存在可改動的層級設置。如下圖所示,發現有部分Label層級設置問題,導致使用UI_New圖集的widget無法合併DrawCall。 通過修改Label的widget的層級,將打斷解除,使得UI_New都在一個DC中。