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

转载请标明出处:http://www.cnblogs.com/zblade/html

最近研究了一下如何在unity中实现c#的热更新,对于整个DLL热更新的过程和方案有一个初步的了解,这儿就写下来,便于后续的深刻调查和方案选择。
1、C# DLL的动态加载和卸载
既然要热更新,那么就是动态的加载c#的DLL,因此第一步就是研究如何实现DLL的动态加载和卸载。
在CLR Via C#中,对于DLL的加载有详细的讲解,这儿就再也不长篇幅的讲解整个过程,简单的来讲,在C#的工程中,都会生成一个默认的程序域appDomain,就叫作DefaultAppDomain吧,在这个程序域的基础上,咱们能够加载多个不一样的程序集。在.Net中,程序集不能卸载,可是能够随着程序域的释放而一块儿释放,因此咱们能够利用程序域来实现程序集(DLL)的加载和释放。

上面的理论来自CLR Via C#, 具体的图为:android

基于这个理论,咱们能够在DefaultAppDomain以外,再屡次建立多个AppDomain,基于AppDomain来实现DLL的加载和卸载。基于此,编写相关的工程测试,参考网上的一个工程来进一步的测试,这儿是原文,文末有相关的代码下载:
在原代码的基础上,进一步构建。首先,构建4个Class Library:

默认工程为MainServer,将Module1和Module2的Build路径设置到MainServer的bin中,这样MainServer就能够加载最新的Module1.DLL/Module2.DLL(PS:这儿的设置很重要,忽略会使得不能加载最新的DLL)
Module1和Module2都在References中添加CommonLib的引用,实现ICalculater接口,各自的实现为:
Module1:

Module2:c#

这样,就是两个不一样的Class Library中,分别实现了ICalculater接口,分别为相加和相乘。在MainServer的主程序入口Program中:windows

 

首先在默认appDomain的基础上,进一步加载2个appDomain,而后分别在这2个程序域的基础上加载DLL。获得的结果为:app

整个步骤都详细的解释了整个执行流程,先构建appDomain,在此基础上,加载dll,而后执行里面的方法。再一个新的appDomain中加载前面加载过的dll,再次执行,相互之间并不冲突。因此appDomain能够一对多个DLL,一个DLL能够被多个不一样的AppDomain加载。测试

 

2、Unity中测试DLL的加载
在第一部分的基础上,咱们进一步的研究如何在Unity中实现Dll的加载,基本的操做步骤能够参考这篇文章:unity dll实现热更新
固然,文章并非彻底的实现热更新,实现的是windows和android平台下,对于dll文件的热更新。对于IOS为何不能热更新,咱们后续会讨论到,先看看安卓和windows下 dll的热更新步骤。
一、新建一个ClassLibrary(类库)的工程,在其中实现对应的类和方法;
二、将该工程导出为DLL;
三、将DLL改成bytes文件,存入Unity工程中的StreamingAssets文件夹下;
四、在工程运行的时候,读取StreamingAssets下的Dll文件,用Assembly.Load(byte[] bytes )的方法,将DLL文件读取出来,进而执行相关的操做。这一步的代码为:

 

对于DLL文件,是执行www.bytes,对于assetbundle文件,则是执行ab.mainAsset转换为TextAsset,进一步获得bytes。在windows和android平台下,都会获得这样的屏幕输出:ui

这个方案的本质,和前面的本质相差不大,unity工程在执行的时候,会构建一个默认的appDomain,Assembly.Load,其实就是在这个程序域上加载Dll,因此相关的实质和前面一个部分相差不大,这就是c#热更新在unity中的应用(IOS不包括)。

下文咱们会讲解IOS为何不支持DLL的热更新,以及如何利用ILRuntime来实现Android和IOS的热更新。spa

相关文章
相关标签/搜索