官文詳解:
https://docs.unity3d.com/Manual/ManagedCodeStripping.html
https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html
代碼裁剪的主要對象包括:.Net系統庫、Unity引擎代碼、插件代碼、游戲邏輯代碼等。
遇到的問題及解決方法
1. 類型轉換錯誤
InvalidCastException: Unable to cast object of type 'BehaviourTree' to type 'DialogueTree'.
對於該類型錯誤,無法有效的確定錯誤原因,最直接的辦法是將整個模塊的Namespace包含到link中以避免此類問題。
2. 無法為抽象類創建對象
Exception: Cannot create an instance of an interface or abstract type for NodeCanvas.Framework.ActionTask
通常原因在於其實現類沒有被保留下來。報錯定位依然不明確。解決辦法同上。
3. 無法解析符號
Type with name 'NodeCanvas.Tasks.Actions.PlayerActions.AnimationAction' could not be resolved.
其中指出的符號,即類型、方法、屬性等,因為沒有被保留下來,導致進行反射調用時無法確定符號意義導致的問題。解決方法很明確,就是將符號寫入link.xml以在strip過程中保留。
4. 找不到Class ID對應的類型
ReportException: UnityLogError Could not produce class with ID 134.
通常是因為Unity引擎的代碼被裁剪,導致在程序運行時找不到對應的類。對此類問題比較方便的一點在於,錯誤信息給出了具體的類(https://docs.unity3d.com/Manual/ClassIDReference.html),要解決問題只需要將查表找到的Class加入到link.xml即可。
5. 找不到構造器
ReflectionException: The reflector requires concrete classes.Type XXX has no constructor. Is it an interface?
這是在使用StrangeIOC框架時遇到的問題。因為框架通過注入->反射來獲取具體類型的實例,所以其中的Mediator、Model、Command、Service都沒有直接引用(在MVCSContext中會進行綁定,以此為根可以找到所有的MVCS類),在strip時由於沒有自定義的構造器,導致錯誤(原因待查)。解決該問題的方式,就是不通過UnityLinker的邏輯來strip這些類,而是將這些類所在的Namespace加入到link.xml。
6. 找不到set函數
ReportException: UnityLogError System.ArgumentException: Set Method not found for 'xxx'
這也是在使用StrangeIOC框架時遇到的問題。因為我們在Mediator、Service類的開頭使用[Inject]標簽來獲取一個Model,而且在邏輯處理部分只用到了屬性的get方法,如果這個Mediator、Service本身沒有被完整保留(添加到Link.xml或者使用了[Preserve]標簽),這樣會導致該條屬性的set方法被裁剪掉,初始化這個類時,會因為找不到屬性的set方法而報錯。