对C#热更新方案ILRuntime的探究

转载请标明出处:http://www.cnblogs.com/zblade/
对于游戏中的热更,目前主流的解决方案,分为Lua(ulua/slua/xlua/tolua)系和ILRuntime表明的c#系。今天就来探究一下ILRuntime是如何实现热更的流程的,新手入门,个中有错误理解,欢迎指正。
ILRuntime的原理
首先说一下lua的热更新基本过程,unity提供了AssetBundle的资源打包方式,这样能够经过资源的对比来更新最新的资源。而lua文件不须要编译,能够被打包进游戏的资源中,在游戏启动的过程当中加载对应的脚本资源,今儿解释执行转换为字节码,在lua的虚拟机中执行,这种自然的设计,能够规避静态语言须要编译的环节。
C#代码在编写后,是须要执行编译的,才能起效,这样若是在手机端,没有对应的编译环境,那么对应的c#代码就没法实现热更。ILRuntime实现的基础,也是基于AssetBundle的资源热更新方式,将须要热更新的c#代码打包成DLL,放在工程的StreamingAssets下,在每次完成资源打包后,对应的DLL会被做为资源热更新出去。这样就规避了编译相关的环节,实现了热更。
文字讲述较为枯燥,看看示例代码是如何执行这个流程的:
一、ILRuntime的相关资料连接
能够在github上查找: ILRuntime
对应的unity3d的工程的例子:ILRuntime U3D例子
 
二、探究ILRuntime的例子
整个例子分为两个部分:
分别是热更新的工程和U3D主工程,那么先看看U3D工程:
较为重要的是两个部分,一个是ILRuntime须要用到的几个环境,重点是Mono.Ceil.20, Mono.Ceil.Pdb,ILRuntime三个文件夹,ILRuntime后续的版本将LitJson也加入进来了。
另外一个关键点就是讲HotFix_Project.dll做为资源加入到StreamingAssets文件夹下,这样就能够被ab打包做为资源热更新出去。
接下来咱们打开HotFix_Project:
 
获得的工程为:
 

重点分析一下引用,能够看到,该工程是引用了UnityEngine/UnityEngine.UI/Assembly-CSharp等几个U3D游戏主工程中的dll的,这样,能够在工程中直接调用对应的u3d相关的dll下的类和方法,示例代码:git

 

只要using UnityEngine申明后,下面的代码就能够继承MonoBehaviour类,天然能够调用其中的相关类和方法。那么到这一步,就能够理解,在HotFix_Project中,咱们是能够调用U3D游戏主工程的类和方法的,只要添加其相关的dll到工程的引用中。这样咱们就完成了HotFix对U3D游戏主工程的调用的一条线路。github

三、U3D游戏主工程调用HotFix_Project中的类型和相关方法
如今的调用都是交互式的,在完成了hotfix对u3d的调用后,咱们接下来看看u3d是如何调用hotfix中的类和方法的。
取咱们最多见和关注的反射做为一个示例,这样能够了解整个调用过程。
首先,须要加载hotfix的dll,来看看相关的代码:
 
整个竖屏截出来的图比较大,跟随箭头来看看流程:
1) 首先MonoBehaviour下的Start执行一个协程;
2) 实例化惟一的appdomain;
3) 加载hotfix的dll和pdb,能够看到,若是咱们热更新相关的dll和pdb,是须要在这一步以前执行的,其实能够放在Awake中执行,固然这儿没有热更,咱们就直接执行dll和pdb的加载;
4) 在完成dll和pdb的加载后,执行assembly的加载,这样咱们能够获取到hotfix中的相关类和方法,属性等相关信息,相关能够查看源码便可了解。
5) 测试如何调用反射:
        Debug.Log("热更DLL中的类型咱们均须要经过AppDomain取得"); var it = appdomain.LoadedTypes["HotFix_Project.InstanceClass"]; Debug.Log("LoadedTypes返回的是IType类型,可是咱们须要得到对应的System.Type才能继续使用反射接口"); var type = it.ReflectionType; Debug.Log("取得Type以后就能够按照咱们熟悉的方式来反射调用了"); var ctor = type.GetConstructor(new System.Type[0]); var obj = ctor.Invoke(null); Debug.Log("打印一下结果"); Debug.Log(obj); Debug.Log("咱们试一下用反射给字段赋值"); var fi = type.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); fi.SetValue(obj, 111111); Debug.Log("咱们用反射调用属性检查刚刚的赋值"); var pi = type.GetProperty("ID"); Debug.Log("ID = " + pi.GetValue(obj, null));
让咱们看看整个流程:
基于appdomain来获取类,而后获取type,对应的invoke, 也能够利用反射来修改对应的field的值。
 
总结:到这儿,咱们就基本理清楚了基于ILRuntime如何实现hotfix和u3d主工程之间的相互调用,能够讲这样一套热更新方式嵌套到游戏的框架中,实现不用lua来实现热更。固然ILRuntime要转换到IL2CPP,仍是有不少地方须要注意的,详情能够参考github上的相关手册。
相关文章
相关标签/搜索