Unity 安卓下DLL熱更新一(核心思想)

你們都知道一談起熱更新的話首選是Ulua這個插件, 其實Unity可使用dll熱更新的,若是你實在不想用Lua來編寫邏輯,0.0請下看Dll+AssetBundle如何實現熱更新的.讓你看完這個文章以後只是認識DLL熱更新的方式和概念,掌握熱更新的實戰框架還須要你本身=。=android

 

咱們一般的作法是編譯成的DLL打成AssetBundle文件, Unity經過WWW下載AB文件獲取裏面DLL.經過反射的方式把裏面的C# 組件綁定到GameObject遊戲物體上面,這就是DLL熱更新的原理. 假設項目採用UGUI系統, 咱們來看看經過以上思想編寫代碼時候遇到的核心問題以下.windows

  1. 我須要如何編寫DLL?
  2. 個人DLL怎麼才能獲取到UnityEngine命名空間類的引用?
  3. 個人DLL須要如何打成AssetBundle?
  4. 程序下載AssetBundle如何讀取裏面DLL?
  5. 如何把腳本綁定起來,實現熱更新UI?

 

1、我須要如何編寫DLL?

首先你須要找到Unity幾個關鍵DLL. UnityEngine.dll,UnityEngine.UI.dll爲了你編寫熱更新代碼有UnityEngine核心類的引用吧.先建立一個C#3.5版本的類庫(點擊項目右鍵->屬性->目標框架3.5), 而後引入UnityEngine.dll和UnityEngine.UI.dll的DLL框架

image

建立完工程以後,咱們編寫一個MyClass繼承MonoBehaviour類iphone

image

 

點擊啓動編譯DLL,編譯成的DLL能夠在項目右鍵->在文件資源器中打開文件夾->Btn目錄->Release和Debug目錄找到MyDll.dll(個人是在Realse目錄下)  咱們把編譯好的DLL,拿到Unity裏面去打包成AssetBundle文件. Unity默認貌似不容許把後綴名DLL打入AssetBundle,咱們修改把MyDll.dll改爲MyDll.bytes名字ui

image

 

把DLL打包成AssetBundle文件代碼以下,this

[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文本便可lua

image

 

給Android下打包好的AssetBundle文件,放入StreamAssetBundleAssets, 代碼會自動幫你複製過去url

image

 

Test核心類spa

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下查看效果圖 插件

image

 

以上只是一個拋磚引玉,但願想使用dll熱更新代碼的能幫助到你.

項目下載地址: http://yunpan.cn/cmE4eL5948ghQ  訪問密碼 df6b

相關文章
相關標籤/搜索