調用熱更代碼中方法,寫在AppDomain中,記錄一下主要幾個方法:c#
AppDomain.LoadAssembly 加載熱更dll跨域
執行熱更代碼的方法,有兩種方式:網絡
- appdomain.Invoke("HotFix_Project.InstanceClass", "StaticFunTest", null, null);
- 預先得到IMethod,能夠減低每次調用查找方法耗用的時間,代碼以下:
//預先得到IMethod,能夠減低每次調用查找方法耗用的時間 IType type = appdomain.LoadedTypes["HotFix_Project.InstanceClass"]; //根據方法名稱和參數個數獲取方法 IMethod method = type.GetMethod("StaticFunTest", 0); appdomain.Invoke(method, null, null);
在熱更工程中監聽主工程的事件,由主工程觸發。app
若是非Action或Func,則須要在主工程中寫適配器,因此建議使用系統自帶的Action和Func。dom
由於跨域繼承必需要註冊適配器。 若是是熱更DLL裏面繼承熱更裏面的類型,不須要任何註冊。ide
Demo中有三個適配器示例,都繼承自CrossBindingAdaptor,適配器中有內部類,繼承或實現接口的方法。性能
public class MonoBehaviourAdapter : CrossBindingAdaptor { public override Type BaseCLRType {get { return typeof(MonoBehaviour); } } public override Type AdaptorType {get { return typeof(Adaptor); } } public override object CreateCLRInstance(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance) { return new Adaptor(appdomain, instance); } //爲了完整實現MonoBehaviour的全部特性,這個Adapter還得擴展,這裏只拋磚引玉,只實現了最經常使用的Awake, Start和Update public class Adaptor : MonoBehaviour, CrossBindingAdaptorType { ILTypeInstance instance; ILRuntime.Runtime.Enviorment.AppDomain appdomain; public Adaptor() { } public Adaptor(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance) { this.appdomain = appdomain; this.instance = instance; } public ILTypeInstance ILInstance { get { return instance; } set { instance = value; } } public ILRuntime.Runtime.Enviorment.AppDomain AppDomain { get { return appdomain; } set { appdomain = value; } } public void Awake() {} void Start(){} void Update(){ } public override string ToString(){ } } }
CLRRedirectionDemo,須要在AppDomain中註冊 RegisterCLRMethodRedirection測試
在熱更工程中調用主工程的代碼時會重定向新的實現,新手能夠從修改CLR生成的綁定代碼開始。this
例子是修改Debug.Log方法,在熱更中打印的日誌也能顯示堆棧信息。lua
相似於slua/tolua/xlua同樣, 把在熱更工程會用到的類添加到列表中,而後生成適配代碼。
ILRuntime提供一個智能分析在熱更工程使用的代碼。
官方例子是調用主工程的方法來啓動協程,我測試熱更工程也能夠調用MonoBehaviour的方法開啓協程。
熱更工程代碼以下:
public static void RunTest() { Debug.Log("熱更工程中開啓協程"); CoroutineDemo.Instance.StartCoroutine(Coroutine()); } static System.Collections.IEnumerator Coroutine() { Debug.Log("開始協程,t=" + Time.time); yield return new WaitForSeconds(3); Debug.Log("等待了3秒,t=" + Time.time); }
那些須要作綁定?Unity的經常使用值類型,好比:Vector3,Vector2
這項操做會提高性能,減小額外的CPU開銷和GC Alloc。
方法:
AppDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder());
Demo 作了十萬次運算,打印日誌以下:
Value: a=(100001.0, 100002.0, 100003.0),dot=0, time = 750ms Value: a=(100001.0, 100002.0, 100003.0),dot=0, time = 1911ms Value: a=(-0.4, -0.8, -1.7, -5.1),dot=-124.7494, time = 604ms Value: a=(-0.4, -0.8, -1.7, -5.1),dot=-124.7494, time = 1550ms Value: a=(100001.0, 100002.0),dot=0, time = 710ms Value: a=(100001.0, 100002.0),dot=0, time = 1902ms
能夠把熱更工程的VS項目(HotFix_Project.csproj)添加到Unity生成的解決方案中(ILRuntimeDemo.sln),在開發期不用兩個工程切換。
因爲Unity 2018和Unity5的目錄結構調整,Library\UnityAssemblies 在Unity2018目錄沒有
因此我在熱更工程引用 Unity_2018_2_7f1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
熱更工程最常作的事情
根據咱們以往的項目使用Lua作爲熱更腳本爲例,咱們在熱更工程作的最多的事情:
在熱更工程中調用主工程的方法,或監聽主工程的事件,監聽Unity組件觸發的事件。
熱更工程調用主工程接口加載資源
熱更工程處理UI代碼邏輯
讀取配置,對配置解析
熱更工程中處理網絡的回調
熱更工程基本處理全部的業務邏輯
由於ILRuntime能夠理解爲藍大寫的C#虛擬機,這個虛擬機要在運行時和Unity的腳本進行交互。
因爲IOS的AOT限制,在運行時ILRuntime中是不知道Unity中的類型,因此須要咱們在主工程寫適配器讓ILRuntime知道如何調用在Unity的代碼,或當Unity的事件觸發時讓ILRuntime可以監聽到。