使用 Mono.Cecil 輔助 Unity3D 手游進(jìn)行性能測試(續(xù))

之前的方法及其局限

問題背景和最初的嘗試見這里海雪。最開始的想法比較簡單声怔,只想著利用 PostprocessBuild 這個事件,來對已經(jīng)準(zhǔn)備好的本地工程文件(iOS 或 Android)中的 .NET 程序集進(jìn)行注入。但是栓霜,這樣做限制很多蜕青。

首先苟蹈,無法對 IL2CPP 作為 Scripting Backend 的情況進(jìn)行注入。因為觸發(fā)這個事件時右核,本地工程文件中沒有 .NET 程序集慧脱,只有 C++ 代碼,無法用 Cecil 進(jìn)行注入贺喝。

第二菱鸥,Android 平臺,用 Mono2x 作為 Scripting Backend 的情況下躏鱼,也需要打包為 Android Studio Project 才能使用氮采。對于直接打包成 apk 的情況,無法簡單的進(jìn)行注入(除非使用解包染苛、注入鹊漠、重新簽名打包的方法,比較麻煩)茶行。

第三躯概,iOS 平臺,即使用 Mono2x 作為 Scripting Backend畔师,也無法成功娶靡。這是因為在 iOS 平臺打包需要先進(jìn)行一個叫 AOT Cross Compiling 的步驟,對所有的程序集生成對應(yīng)的 .dll.s 文件看锉。這些文件包含的信息會在運行時被校驗姿锭,如果我篡改了程序集,而沒有理會 .dll.s 文件伯铣,在運行時會報錯艾凯。錯誤信息類似

A script behaviour (probably XXX?) has a different seralization layout when loading. (Read ** bytes but expected ** bytes)

Did you #ifdef UNITY_EDITOR a section of your serialized properties in any of your scripts?

其中 XXX 是 .NET 腳本名稱,兩組星號表示兩個不同值懂傀。這錯誤最終導(dǎo)致腳本加載失敗趾诗,無法運行游戲。與錯誤信息描述不同,我并沒有在出問題的腳本上寫任何條件編譯的代碼恃泪。要想解決這個問題郑兴,估計需要篡改 .dll.s 文件才可以,仍然是很不經(jīng)濟(jì)的贝乎。

篡改編譯器的方法

接下來一個辦法情连,就是對 Unity 的 C# 編譯器 mcs.exe 進(jìn)行篡改。我沒有深入實驗览效,因為幾個簡單的實驗就耗費了一天多的時間却舀。我主要嘗試了兩種方法,當(dāng)然锤灿,都沒成功挽拔。

方法一,將原 mcs.exe 重命名(如 mcs1.exe)但校,而后自己寫一個 .NET 控制臺應(yīng)用程序螃诅,占據(jù)原來 mcs.exe 的位置,在其中用 System.Diagnostic.Process 類來啟動 mcs1.exe状囱。這個過程中术裸,我對 Process 對象的一些配置,如環(huán)境變量(EnvironmentVariables 屬性)亭枷、輸入輸出重定向(RedirectStandardXXX 屬性)進(jìn)行了多種排列組合袭艺,仍無法正確調(diào)用 mcs1.exe,就更不要說調(diào)用之后的事情了叨粘。

方法二猾编,直接在 mcs.exe 中注入代碼。因為 mcs.exe 也是一個 .NET 應(yīng)用程序宣鄙,并且看上去未經(jīng)混淆袍镀,所以直接注入是可行的默蚌。即冻晤,「把向游戲程序集中注入代碼的代碼,注入到編譯器中绸吸”腔。」這樣做主要的問題,是 mcs.exe 的輸出目錄是臨時文件夾锦茁,無法保證其中有我們依賴的(如注入后寫入程序集時攘轩,需要用 Mono.Cecil 的 DefaultAssemblyResolver 進(jìn)行解析的)程序集。

通過 OnPostprocessScene 回調(diào)事件來進(jìn)行注入

Unity 雖然沒有在執(zhí)行 mcs.exe 和后續(xù)步驟(IL2CPP码俩、Android 打包 apk度帮、iOS 上的 AOT 交叉編譯等)之間提供回調(diào),但是回調(diào)事件 OnPostprocessScene 目前是確保在它們之間至少觸發(fā)一次的。多虧 https://github.com/rayosu/UnityDllInjector 提醒了我笨篷。在這個事件回調(diào)中處理 DLL瞳秽,理論上在任何平臺、任何 Scripting Backend 上都可以有效注入率翅。實現(xiàn)過程中有幾個要點需要注意:

  • 事件 OnPostprocessScene 對應(yīng) Build Settings 中指定打包的場景個數(shù)练俐,所以它可能執(zhí)行多次,故而需要防止重復(fù)冕臭。除了上述 UnityDllInjector 中提供的方法腺晾,還可以直接把注入標(biāo)記寫入你的目標(biāo)程序集。但值得注意的是辜贵,新增一個用于標(biāo)記的空類在 iOS + Mono2x 下又是不好用的悯蝉,猜測還和 AOT 交叉編譯有關(guān)。保險的做法之一念颈,是在游戲代碼中保留幾個 bool 常量泉粉,值為 false,注入前檢查相應(yīng)的值榴芳,如果為 true 則跳過嗡靡,否則注入。注入完成后窟感,將相應(yīng)的 bool 常量篡改為 true 即可讨彼。

  • 游戲腳本對應(yīng)的程序集,在注入時一定處于和 Assets 同級的 Library 下的 ScriptAssemblies 文件夾下柿祈,但要注意你依賴的 Unity 程序集哈误。我使用 UnityDllInjector 提供的方法,依然不能保證獲取到需要的程序集躏嚎。最終我采用的方法是蜜自,使用 EditorApplication.applicationContentsPath 獲取 Unity 安裝目錄,在其中 Data/Managed 目錄里尋找必要的程序集卢佣。

目前我測試了 Android + Mono/IL2CPP 和 iOS + IL2CPP重荠,都沒有問題。iOS + Mono2x 可能由于我們項目本身的一些問題虚茶,在 Xcode 鏈接階段有一些問題戈鲁。


舊文搬運,2017-06-15 首發(fā)于博客園嘹叫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婆殿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子罩扇,更是在濱河造成了極大的恐慌婆芦,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異消约,居然都是意外死亡癌压,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門荆陆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滩届,“玉大人,你說我怎么就攤上這事被啼≈南” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵浓体,是天一觀的道長泡挺。 經(jīng)常有香客問我,道長命浴,這世上最難降的妖魔是什么娄猫? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮生闲,結(jié)果婚禮上媳溺,老公的妹妹穿的比我還像新娘。我一直安慰自己碍讯,他們只是感情好悬蔽,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捉兴,像睡著了一般蝎困。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上倍啥,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天禾乘,我揣著相機(jī)與錄音,去河邊找鬼虽缕。 笑死始藕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的彼宠。 我是一名探鬼主播鳄虱,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼弟塞,長吁一口氣:“原來是場噩夢啊……” “哼凭峡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起决记,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤摧冀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體索昂,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡建车,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了椒惨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缤至。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖康谆,靈堂內(nèi)的尸體忽然破棺而出领斥,到底是詐尸還是另有隱情,我是刑警寧澤沃暗,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布月洛,位于F島的核電站,受9級特大地震影響孽锥,放射性物質(zhì)發(fā)生泄漏嚼黔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一惜辑、第九天 我趴在偏房一處隱蔽的房頂上張望唬涧。 院中可真熱鬧,春花似錦盛撑、人聲如沸爵卒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钓株。三九已至,卻和暖如春陌僵,著一層夾襖步出監(jiān)牢的瞬間轴合,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工碗短, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留受葛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓偎谁,卻偏偏與公主長得像总滩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子巡雨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容