使用 Mono.Cecil 輔助 Unity3D 手遊進行性能測試

Unity3D 引擎在 UnityEngine 名字空間下,提供了 Profiler 類(Unity 5.6 開始似乎改變了這個名字空間),用於輔助對項目性能進行測試。以 Android 平臺爲例,在構建之前,需要在 Unity 的 File/Build Settings 菜單項彈出的窗口中,勾選 Development Build 一項。後用 adb forward 的方式,將 Android 設備的 TCP 輸出轉發到電腦,實現和 Unity Profiler 的連接(網上很容易找到這個過程的具體描述,如這裏)。但是 Unity Profiler 默認只提供部分方法/函數,尤其是 Unity 內置方法/函數的性能採樣,如果想 Profile 自己項目的代碼段,就必須在代碼段入口和出口加上:
方法出口注入代碼稍微有些麻煩。儘管 IL 級別的函數都是以一個返回指令結束的,但直接在返回指令之前插入新的指令是不夠的。因爲很多時候,返回指令是由跳轉指令直接跳轉過去的。而對於我們在 C# 中獲取的指令容器,跳轉指令保存了其跳轉目標的引用。因此,我們不僅需要在返回指令前插入我們需要的指令(對 Profiler.EndSample 包裝方法的調用),還要將跳轉目標爲該返回指令的跳轉指令的目標,修改爲我們新增的指令。這裏有詳盡的關於 IL 指令的列表。對應 Cecil 中 OpCodes 類中的常量,我們可以過濾出跳轉指令,並用 Operand 屬性獲取或修改其跳轉目標。
修改完成後,需要對當前的模塊對象 moduleDef 調用 moduleDef.Write(assemblyPath, new WriterParameters { WriteSymbols = true }) 來寫回程序集文件。這個調用中,第二個參數的含義,是把新增的符號也寫入程序集(比如我們調用的該程序集之外的方法)。
在注入完成後,繼續 Android 平臺的原生構建生成 apk 包,安裝進設備,將設備連接電腦,即可在 Unity 的 Profiler 窗口中看到新增的性能採樣信息。

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