1. 程式人生 > >徹底解決IL2CPP 開啟Strip Engine Code選項後帶來的崩潰問題

徹底解決IL2CPP 開啟Strip Engine Code選項後帶來的崩潰問題

 

IL2CPP根據C#生成的Cpp程式碼行數巨大,達到百萬行級別,進而引起iOS平臺可執行檔案超過60MB的問題。因此在適當的時候有必要對UnityEngine下的程式碼進行Strip。但是這樣做容易帶來如下的問題:
ReportException: UnityLogError Could not produce class with ID XXX.
This could be caused by a class being stripped from the build even though it is needed.
Try disabling 'Strip Engine Code' in Player Settings.
其中XXX代表被Strip掉但是資源所需要的YAML ClassID.

之所以會出現這樣的問題,目前的猜測是Unity進行Code Strip時,只分析一下幾個方面所用到的類:

    C#程式碼:Assembly-CSharp.dll、firstpass.dll、各外掛Dll.
    Resources資源:BuildSettings裡面的場景引用的資源和Resources資料夾下面的資源
    link.xml:Assets資料夾下面開發者可建立一個link.xml作為Code Strip白名單。另外觀察Jenkins打包日誌可以發現Unity安裝目錄下playbackEngines資料夾內含Unity自己的一套link.xml白名單

這樣來看上述Crash發生的原因就比較明確了,那些打入AssetBundle的檔案使用了Unity的其他類,但是同時在以上三個分析範圍之外,Unity會將其Strip掉;當從AssetBundle進行載入時,由於缺少對應的類造成Deserialize失敗,進而引起崩潰。

瞭解以上原因後,解決方案就呼之欲出了。只需要得到資源所用到的所有Unity引擎類,將其加入至link.xml即可。

    UnityEngine.Dll: 一般的做法是獲取所有Prefab、場景檔案中的元件進行彙總,這裡說一個更簡單的辦法,直接觀察Unity YAML的結構,很容易就能發現以下格式指明瞭Unity引擎類的ID:
    --- !u!XXX
    其中XXX代表YAML ClassID,去Unity Manual上查表即可得到對應的類名。
    UnityEngine.UI.Dll:沒有YAML ClassID可查,只能加載出Prefab時Get一下Component來判斷,可能遺漏的情況是ScriptableObject中對其進行了引用。
    UnityEditor.Dll:一個很特殊的情況,如果AssetBundle裡使用到了AniamtorController,那麼就需要UnityEditor下面的AnimatorController相關的幾個類(還有AnimationState、Transition之類),直接新增進link.xml顯然沒什麼意義。解決方案也很簡單,在Resources下面增加一個空的AnimatorController,讓Unity自己處理。

值得注意的是,這一塊Unity自己的Bug也不少,出現奇怪的問題不妨先去issueTracker和Fix List看看 :)

PS: IL2CPP相關的實現其實就在Unity的安裝目錄下,包含完整的從分析到生成C++、編譯的邏輯,有興趣可以逆向Dll看一下。
---------------------
作者:逝水追風
來源:CSDN
原文:https://blog.csdn.net/zhangdi2017/article/details/79168180
版權宣告:本文為博主原創文章,轉載請附上博文連結!