大家都知道一談起熱更新的話首選是Ulua這個插件, 其實Unity可以使用dll熱更新的,如果你實在不想用Lua來編寫邏輯,0.0請下看Dll+AssetBundle如何實現熱更新的.讓你看完這個文章之后只是認識DLL熱更新的方式和概念,掌握熱更新的實戰框架還需要你自己=。=
我們通常的做法是編譯成的DLL打成AssetBundle文件, Unity通過WWW下載AB文件獲取里面DLL.通過反射的方式把里面的C# 組件綁定到GameObject游戲物體上面,這就是DLL熱更新的原理. 假設項目采用UGUI系統, 我們來看看通過以上思想編寫代碼時候遇到的核心問題如下.
- 我需要如何編寫DLL?
- 我的DLL怎么才能獲取到UnityEngine命名空間類的引用?
- 我的DLL需要如何打成AssetBundle?
- 程序下載AssetBundle如何讀取里面DLL?
- 如何把腳本綁定起來,實現熱更新UI?
一、我需要如何編寫DLL?
首先你需要找到Unity幾個關鍵DLL. UnityEngine.dll,UnityEngine.UI.dll為了你編寫熱更新代碼有UnityEngine核心類的引用吧.先創建一個C#3.5版本的類庫(點擊項目右鍵->屬性->目標框架3.5), 然后引入UnityEngine.dll和UnityEngine.UI.dll的DLL
創建完工程之后,我們編寫一個MyClass繼承MonoBehaviour類
點擊啟動編譯DLL,編譯成的DLL可以在項目右鍵->在文件資源器中打開文件夾->Btn目錄->Release和Debug目錄找到MyDll.dll(我的是在Realse目錄下) 我們把編譯好的DLL,拿到Unity里面去打包成AssetBundle文件. Unity默認貌似不允許把后綴名DLL打入AssetBundle,我們修改把MyDll.dll改成MyDll.bytes名字
把DLL打包成AssetBundle文件代碼如下,
[MenuItem("Assets/Build Android DLL")] public static void BuildAssetsAndroidDll() { Object mainAsset = AssetDatabase.LoadMainAssetAtPath("Assets/Dll/MyDLL.bytes"); BuildPipeline.BuildAssetBundle(mainAsset, null, Application.dataPath + "\\Dll\\myassets.android", BuildAssetBundleOptions.None,BuildTarget.Android); if (File.Exists(androidStreamUrl)) { File.Delete(androidStreamUrl); } //拷貝到Stream目錄下方便程序下載AB文件 File.Copy(Application.dataPath + "\\Dll\\myassets.android", androidStreamUrl); }
再來看下我們Unity需要做那些操作,就是新創建一個場景添加一個Text文本即可
給Android下打包好的AssetBundle文件,放入StreamAssetBundleAssets, 代碼會自動幫你復制過去
Test核心類
using UnityEngine; using System.Collections; using System.Reflection; using System; using System.IO; using UnityEngine.UI; public class Test : MonoBehaviour { public string url; public string str; public Text myAgeText; public void Awake() { Application.logMessageReceived += Application_logMessageReceived; } void Application_logMessageReceived(string condition, string stackTrace, LogType type) { str += "\r\n" + condition; } public void OnGUI() { GUI.Box(new Rect(0, 0, 800, 800), str); } // Use this for initialization IEnumerator Start () { yield return new WaitForSeconds(2); if (Application.platform == RuntimePlatform.WindowsEditor) { url = @"file://"+Application.dataPath + "\\Dll\\myassets.windows"; }else if(Application.platform == RuntimePlatform.Android) { url = Application.streamingAssetsPath + "/myassets.android"; } else if (Application.platform == RuntimePlatform.IPhonePlayer) { url = Application.streamingAssetsPath + "/myassets.iphone"; } Debug.Log("url: " + url); WWW www = new WWW(url); yield return www; if(www.error != null) { Debug.Log("加載 出錯"); } if(www.isDone) { Debug.Log("加載完畢"); AssetBundle ab = www.assetBundle; try { //先把DLL以TextAsset類型取出來,在把bytes給Assembly.Load方法讀取准備進入反射操作 Assembly aly = System.Reflection.Assembly.Load(((TextAsset)www.assetBundle.mainAsset).bytes); //獲取DLL下全部的類型 foreach (var i in aly.GetTypes()) { //調試代碼 Debug.Log(i.Name); str += "\r\n" + i.Name; //添加組件到當前GameObject下面 Component c = this.gameObject.AddComponent(i); //然后類名是MyClass,就把文本引用賦值給MyClass.platefaceText屬性. if (i.Name == "MyClass") { FieldInfo info = c.GetType().GetField("platefaceText"); info.SetValue(c, myAgeText); } } } catch (Exception e) { Debug.Log("加載DLL出錯"); Debug.Log(e.Message); } } } }
在Windows下查看效果圖
以上只是一個拋磚引玉,希望想使用dll熱更新代碼的能幫助到你.
項目下載地址: http://yunpan.cn/cmE4eL5948ghQ 訪問密碼 df6b






