對C#熱更新方案ILRuntime的探究

轉載請標明出處:http://www.cnblogs.com/zblade/
對於遊戲中的熱更,目前主流的解決方案,分爲Lua(ulua/slua/xlua/tolua)系和ILRuntime表明的c#系。今天就來探究一下ILRuntime是如何實現熱更的流程的,新手入門,箇中有錯誤理解,歡迎指正。
ILRuntime的原理
首先說一下lua的熱更新基本過程,unity提供了AssetBundle的資源打包方式,這樣能夠經過資源的對比來更新最新的資源。而lua文件不須要編譯,能夠被打包進遊戲的資源中,在遊戲啓動的過程當中加載對應的腳本資源,今兒解釋執行轉換爲字節碼,在lua的虛擬機中執行,這種自然的設計,能夠規避靜態語言須要編譯的環節。
C#代碼在編寫後,是須要執行編譯的,才能起效,這樣若是在手機端,沒有對應的編譯環境,那麼對應的c#代碼就沒法實現熱更。ILRuntime實現的基礎,也是基於AssetBundle的資源熱更新方式,將須要熱更新的c#代碼打包成DLL,放在工程的StreamingAssets下,在每次完成資源打包後,對應的DLL會被做爲資源熱更新出去。這樣就規避了編譯相關的環節,實現了熱更。
文字講述較爲枯燥,看看示例代碼是如何執行這個流程的:
一、ILRuntime的相關資料連接
能夠在github上查找: ILRuntime
對應的unity3d的工程的例子:ILRuntime U3D例子
 
二、探究ILRuntime的例子
整個例子分爲兩個部分:
分別是熱更新的工程和U3D主工程,那麼先看看U3D工程:
較爲重要的是兩個部分,一個是ILRuntime須要用到的幾個環境,重點是Mono.Ceil.20, Mono.Ceil.Pdb,ILRuntime三個文件夾,ILRuntime後續的版本將LitJson也加入進來了。
另外一個關鍵點就是講HotFix_Project.dll做爲資源加入到StreamingAssets文件夾下,這樣就能夠被ab打包做爲資源熱更新出去。
接下來咱們打開HotFix_Project:
 
獲得的工程爲:
 

重點分析一下引用,能夠看到,該工程是引用了UnityEngine/UnityEngine.UI/Assembly-CSharp等幾個U3D遊戲主工程中的dll的,這樣,能夠在工程中直接調用對應的u3d相關的dll下的類和方法,示例代碼:git

 

只要using UnityEngine申明後,下面的代碼就能夠繼承MonoBehaviour類,天然能夠調用其中的相關類和方法。那麼到這一步,就能夠理解,在HotFix_Project中,咱們是能夠調用U3D遊戲主工程的類和方法的,只要添加其相關的dll到工程的引用中。這樣咱們就完成了HotFix對U3D遊戲主工程的調用的一條線路。github

三、U3D遊戲主工程調用HotFix_Project中的類型和相關方法
如今的調用都是交互式的,在完成了hotfix對u3d的調用後,咱們接下來看看u3d是如何調用hotfix中的類和方法的。
取咱們最多見和關注的反射做爲一個示例,這樣能夠了解整個調用過程。
首先,須要加載hotfix的dll,來看看相關的代碼:
 
整個豎屏截出來的圖比較大,跟隨箭頭來看看流程:
1) 首先MonoBehaviour下的Start執行一個協程;
2) 實例化惟一的appdomain;
3) 加載hotfix的dll和pdb,能夠看到,若是咱們熱更新相關的dll和pdb,是須要在這一步以前執行的,其實能夠放在Awake中執行,固然這兒沒有熱更,咱們就直接執行dll和pdb的加載;
4) 在完成dll和pdb的加載後,執行assembly的加載,這樣咱們能夠獲取到hotfix中的相關類和方法,屬性等相關信息,相關能夠查看源碼便可瞭解。
5) 測試如何調用反射:
        Debug.Log("熱更DLL中的類型咱們均須要經過AppDomain取得"); var it = appdomain.LoadedTypes["HotFix_Project.InstanceClass"]; Debug.Log("LoadedTypes返回的是IType類型,可是咱們須要得到對應的System.Type才能繼續使用反射接口"); var type = it.ReflectionType; Debug.Log("取得Type以後就能夠按照咱們熟悉的方式來反射調用了"); var ctor = type.GetConstructor(new System.Type[0]); var obj = ctor.Invoke(null); Debug.Log("打印一下結果"); Debug.Log(obj); Debug.Log("咱們試一下用反射給字段賦值"); var fi = type.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); fi.SetValue(obj, 111111); Debug.Log("咱們用反射調用屬性檢查剛剛的賦值"); var pi = type.GetProperty("ID"); Debug.Log("ID = " + pi.GetValue(obj, null));
讓咱們看看整個流程:
基於appdomain來獲取類,而後獲取type,對應的invoke, 也能夠利用反射來修改對應的field的值。
 
總結:到這兒,咱們就基本理清楚了基於ILRuntime如何實現hotfix和u3d主工程之間的相互調用,能夠講這樣一套熱更新方式嵌套到遊戲的框架中,實現不用lua來實現熱更。固然ILRuntime要轉換到IL2CPP,仍是有不少地方須要注意的,詳情能夠參考github上的相關手冊。
相關文章
相關標籤/搜索