大家都知道一谈起热更新的话首选是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

创建完工程之后,我们编写一个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

Unity 安卓下DLL热更新一(核心思想)的更多相关文章

  1. Unity应用的iOS热更新

    Unity应用的iOS热更新 作者:丁治宇 Unity TechnologiesChina Agenda •  什么是热更新 •  为何要热更新 •  如何在iOS 上对Unity 应用进行热更新 • ...

  2. Unity3d dll 热更新 基础框架

    APK包装到用户手机上后,代码如何更新,总不能全用LUA吧?特别是代码非常多的战斗手游 昨晚上有了dll 热更新的想法,今天做了一天的实验,也遇到些坑,这里总结下 工作环境: U3D5.3.2 + v ...

  3. Ionic APP 热更新 之 产品发布状态下的热更新搭建,去local-dev-addon插件

    上一篇,我们介绍了在本地开发环境下的ionic项目热更新测试, 本文,我们将详细说明如何在去掉cordova-hot-code-push-local-dev-addon插件的情况下,实现热更新. 使用 ...

  4. Unity实现c#热更新方案探究(二)

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.IOS对DLL热更新的禁止 紧接上文,继续对C#热更新的研究.上文中,已经说了如何基于appDomain来实现对DLL ...

  5. Unity实现c#热更新方案探究(一)

    转载请标明出处:http://www.cnblogs.com/zblade/ 最近研究了一下如何在unity中实现c#的热更新,对于整个DLL热更新的过程和方案有一个初步的了解,这儿就写下来,便于后续 ...

  6. Unity实现c#热更新方案探究(三)

    转载请标明出处:http://www.cnblogs.com/zblade/ 前面两篇文章从头到尾讲解了C#热更新的一些方案,从程序域来加载和卸载DLL,到使用ILRuntime来实现安卓和IOS平台 ...

  7. Unity官方发布热更新方案性能对照

    孙广东  2016.3.11 Unity应用的iOS热更新 作者:丁治宇 Unity TechnologiesChina Agenda •  什么是热更新 •  为何要热更新 •  怎样在iOS 上对 ...

  8. unity热更新方案对比

    Unity应用的iOS热更新 •  什么是热更新 •  为何要热更新 •  怎样在iOS 上对Unity 应用进行热更新 •  支持Unity iOS 热更新的各种Lua 插件的对照 什么是热更新 • ...

  9. APP热更新方案

    为什么要做热更新 当一个App发布之后,突然发现了一个严重bug需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包App.测试.向各个应用市场和渠道换包.提示用户升级.用户下载.覆盖安装. 重 ...

随机推荐

  1. Java清洁:终结处理和垃圾回收

    一般情况:Java有垃圾回收机制负责回收无用对象占据的内存资源. 特殊情况:假定你的对象(并非使用new)获得一块特殊的内存区域,由于垃圾回收器只知道释放那些经由new分配的内存,所以它不知道如何释放 ...

  2. javasscript学习笔记 之 数组学习二 数组的所有方法

    1.push() 和 pop()  栈的方法 后进先出 push() 该方法是向数组末尾添加一个或者多个元素,并返回新的长度. push()方法可以接收任意数量的参数,把它们逐个添加到数组的末尾,并返 ...

  3. windows下netstat -aon命令

    windows平台下netstat常用命令 C:\Users\Administrator>netstat --help 显示协议统计和当前 TCP/IP 网络连接. NETSTAT [-a] [ ...

  4. C#基础:命令解析

    1.普通格式命令的解析 例如: RENA<SP>E:\\A.txt<SP>C:\\B.txt<CRLF> (SP -> 空格,CRLF -> 回车加换行 ...

  5. 从free命令看Linux内存管理

    free命令是Linux系统下用来查看内存使用情况的,例如: $ free -h total used free shared buffers cached Mem: 7.8G 6.6G 1.3G 0 ...

  6. (转)union和union all的区别

    Union因为要进行重复值扫描,所以效率低.如果合并没有刻意要删除重复行,那么就使用Union All 两个要联合的SQL语句 字段个数必须一样,而且字段类型要“相容”(一致): 如果我们需要将两个s ...

  7. C#中new和override的区别

    override是指“覆盖”,是指子类覆盖了父类的方法.子类的对象无法再访问父类中的该方法.(签名必须相同) new是指“隐藏”,是指子类隐藏了父类的方法,当然,通过一定的转换,可以在子类的对象中访问 ...

  8. 错误记录--更改tomcat端口号方法,Several ports (8005, 8080, 8009)

    启动Tomcat服务器报错: Several ports (8005, 8080, 8009) required by Tomcat v5.5 Server at localhost are alre ...

  9. 关于Eclipse中Jsp页面打不开并且显示Failed to create the part's controls的解决办法

    问题描述:同事从svn上导入的一个项目,jdk都设置好了以后,java.xml.html等文件都能打开,唯独jsp文件打不开,并且显示Failed to create the part's contr ...

  10. 《转载》深入理解 cocos2d-x 坐标系

    原文地址:http://www.cnblogs.com/lyout/p/3292702.html. 首先我们添加两个测试精灵(宽:27,高:40)到场景里面: CCSprite *sprite1 = ...