前言
我們有一個用Unity引擎開發了二十個月的mmo arpg手游項目,在安卓已經測試三輪了,出於IOS的熱的考慮且結合我們的情況:全部代碼都是純C#開發非Lua,所以計划使用ILRuntime熱更,這里記錄我們把這個項目用上ILRuntime熱更的過程,包括遇到的困難和如何解決的。其它類型項目或其它項目架構的重點問題可能不一樣
項目環境:ILRuntime版本 1.6.3 , Unity版本:2018.4.15f1
ILRuntime熱更遇到問題
把項目大部分代碼都搬到ILRuntime執行后,先說說從表現上我們遇到的問題:
GC Allow非常頻繁
每隔5秒左右就會執行一次GC Allow,每次耗時200ms導致降幀,在手機上的GC Allow間隔時間會長一些
對象管理耗時
每個對象的update耗時在0.5~1ms,當場景內有100個對象時,只有幾幀,基本卡住不動了。
對象管理耗時主要分布在對象的狀態維護,對象顯示/隱藏,頭頂文字處理
空函數調用
一些空的Update函數調用,耗時在0.7ms
資源創建和銷毀
在戰斗過程中,技能特效的加載和創建第一次會頓一下
多人幀率低
場景內多人移動時,幀率會降低
界面打開瞬間掉幀
在界面第一次打開時,掉幀特別明顯,這是因為在界面打開時有很多的邏輯
官方建議這些內容放主工程
通過咨詢ILRuntime的作者藍大,他建議把這些內容放在主工程
- 移動
- 資源管理
- UI框架
- 頭頂文字
- 戰斗(視情況是否放主工程)
- 對象管理放主工程
而我們項目由於完成度高,代碼交叉調用多,只有極少部分內容放在主工程,其它內容全部放在熱更工程中
通過Profiler看問題
好在是C#代碼,把熱更代碼生成dll之后,在Unity的Profiler中查看耗時大的函數,可以看到具體的文件和函數名,這為排查重點耗時大戶提供了極大的便利。
通過在Profiler中看到最大頭的部分:
- 游戲中每個對象的update函數
- 紅點檢測會頻繁遍歷背包
- 一些網絡包的處理
- 某些邏輯代碼存在重復注冊事件,或多次進入玩法出現函數重復調用
為什么對象的Update耗時會這么大?因為在主城中,一個地圖中所有的npc,傳送點,采集物都是由客戶端本地管理,就算不在視野內也會執行Update,只是外觀不顯示。
而玩家則是由服務器的視野來控制,不在視野內的對象不會存在於客戶端。
我們的解決方案
目前我們已經采取的解決方案有這些:
-
每個對象的Update進行分幀處理,不在同一幀處理,注意:僅對靜止對象這樣處理
-
去掉空的Update
-
把foreach改成for
-
把全局變量改成局部變量
-
修改紅點的部分邏輯,避免每秒計算結果