UnityTips:不要在發佈版本中實現OnGUI方法

0x00 問題

不知道大家是否在調試Unity應用性能的時候發現過一條常見的Marker:UIEvents.IMGUIRenderOverlays。

很多情況下,這條叫做UIEvents.IMGUIRenderOverlays的Marker下會有持續的GC內存分配以及CPU時間的開銷。如下圖所示:


可以看到在這個截圖中,UIEvents.IMGUIRenderOverlays的GC分配爲368B,時間開銷爲0.27ms,並且是每幀持續如此的輸出。

0x01 原因

一旦發現UIEvents.IMGUIRenderOverlays中花費了大量的主線程CPU時間以及GC分配,這就表明在項目的代碼庫中的某處使用了Unity的即時模式GUI系統:即便是在代碼庫中僅出現一次OnGUI方法,也會導致IMGUI系統在遊戲運行時進行初始化和處理。
重要的是IMGUI非常低效,不適合生產代碼。

void OnGUI() { if(GUI.Button(new Rect(100, 100, 100, 100), "Load UI")) { //TODO } }

  

檢查一下我們的項目,果然在一個測試腳本中發現了一個OnGUI方法的實現。Ok,現在我們把OnGUI方法註釋掉再來看一看Unity Profiler提供的數據。


可以發現,去掉了OnGUI方法之後,UIEvents.IMGUIRenderOverlays的開銷從之前的每幀GC分配368B降到了0B,CPU的時間開銷從0.27ms降到了0.01ms。
如果點開UIEvents.IMGUIRenderOverlays的內容,可以看到一個叫做GUI.Repaint的Marker,這個Marker所對應的Unity的底層方法會收集所有實現了OnGUI方法的腳本,對這個OnGUI方法的實現進行繪製。

可以看到,針對OnGUI的使用不僅僅不易於維護代碼的可讀性,甚至是可能會引起不必要的開銷,哪怕只有一個OnGUI的實現不小心隨發佈版本一同發佈都會帶來這種開銷。

因此一個小建議是,大家可以在項目的代碼庫中搜索OnGUI方法並手動刪除它們,或通過使用合適的#if預處理語句將它們包起來,以確保將它們從發佈構建中移除。

https://docs.microsoft.com/zh-cn/learn/?WT.mc_id=DT-MVP-5001664

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章