unity dll实现热更新

大家都知道一谈起热更新的话首选是Ulua这个插件, 其实Unity可以使用dll热更新的,如果你实在不想用Lua来编写逻辑,0.0请下看Dll+AssetBundle如何实现热更新的.让你看完这个文章之后只是认识DLL热更新的方式和概念,掌握热更新的实战框架还需要你自己=。=

 

我们通常的做法是编译成的DLL打成AssetBundle文件, Unity通过WWW下载AB文件获取里面DLL.通过反射的方式把里面的C# 组件绑定到GameObject游戏物体上面,这就是DLL热更新的原理. 假设项目采用UGUI系统, 我们来看看通过以上思想编写代码时候遇到的核心问题如下.

  1. 我需要如何编写DLL?
  2. 我的DLL怎么才能获取到UnityEngine命名空间类的引用?
  3. 我的DLL需要如何打成AssetBundle?
  4. 程序下载AssetBundle如何读取里面DLL?
  5. 如何把脚本绑定起来,实现热更新UI?

 

一、我需要如何编写DLL?

首先你需要找到Unity几个关键DLL. UnityEngine.dll,UnityEngine.UI.dll为了你编写热更新代码有UnityEngine核心类的引用吧.先创建一个C#3.5版本的类库(点击项目右键->属性->目标框架3.5), 然后引入UnityEngine.dll和UnityEngine.UI.dll的DLL

image

创建完工程之后,我们编写一个MyClass继承MonoBehaviour类

image

 

点击启动编译DLL,编译成的DLL可以在项目右键->在文件资源器中打开文件夹->Btn目录->Release和Debug目录找到MyDll.dll(我的是在Realse目录下)  我们把编译好的DLL,拿到Unity里面去打包成AssetBundle文件. Unity默认貌似不允许把后缀名DLL打入AssetBundle,我们修改把MyDll.dll改成MyDll.bytes名字

image

 

把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文本即可

image

 

给Android下打包好的AssetBundle文件,放入StreamAssetBundleAssets, 代码会自动帮你复制过去

image

 

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下查看效果图

image

 

以上只是一个抛砖引玉,希望想使用dll热更新代码的能帮助到你.

  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值