极速入门ILRuntime热更新


阅读本片文章大约需要15分钟,也可以参考雷蒙德老师的B站视频讲解,它可以帮助你更快速理解其中的技术概念以及如何实战:极速入门ILRuntime热更新

关于我们

在这里插入图片描述

 首先,简单的介绍一下我们机构,我们是优梦创客,目标是帮助各位同学创作一款大家爱玩的游戏。我是这节课的主讲老师雷蒙德。在这一行业有14年的从业经验,做过程序员、技术经理、教学经理,目前是优梦创客的创始人。我参与过的成功的项目作品有:《传奇世界》、《神迹》、《疯狂赛车》、《剑网3》等。
在这里插入图片描述

  • 如果需要和我进行技术交流请扫第一个二维码。
  • 如果需要领取课程福利,比如课程资料、课程回放,了解课程系统详情,请扫第二个二维码。
  • 如果需要进群和其他小伙伴一起学习,请扫第三个二维码。
    接下来就进入我们的课程吧。

1.认识ILRuntime

在这里插入图片描述

 什么是热更新:
 热更新是指软件不通过运营商店的软件版本更新审核,直接通过应用自行下载的软件数据更新的行为。简单来说,就是在用户下载安装APP之后,打开App时遇到的即时更新。热更新是一种各大手游等众多App常用的更新方式。目前市面上的常见热更新方案有ILRuntime、ToLua、Xlua等。
 为什么需要ILRuntime:

  • ILRuntime是基于C#平台的,所以ILRuntime的使用只需要会C#语言即可。
  • ILRuntime的热更新是非常快捷且可靠的,因为它的底层使用的是.NET的运行环境,所以只要.NET运行时的环境稳定,ILRuntime就是稳定的。
  • ILRuntime也可以在不支持JIT的硬件环境下进行代码的热更新。例如IOS环境出于安全考虑不允许在程序运行期间动态加载一块程序代码到内存中运行,所以使用ILRuntime或XLua可以实现代码的热更新。
    注:JIT为即时代码编译运行功能。
    在这里插入图片描述
    ILRuntime的优势:
  • 如果使用Lua的热更,需要在Lua脚本和C#脚本之间加一层脚本的绑定,而ILRuntime不需要。
  • ILRuntime可以直接使用VS2015以上版本进行开发,ILRuntime的解译引擎支持.NET4.6编译的DLL。
  • ILRuntime的执行效率高,是L#的10-20倍。如果不是使用反射,而是使用基于CLR绑定的方式可以使跨域调用的性能达到sLua的2倍左右。
  • ILRuntime可以支持跨域继承。即ILRuntime的脚本可以继承其他C#的类。
  • ILRuntime支持泛型,这点Lua是不可以的。
  • ILRuntime拥有VisualStudio的调试插件,因此它的调试非常方便。
    在这里插入图片描述
    C#与Lua的对比:
  • C#和Lua作为热更新方案各有优缺点。
  • Lua对于Unity项目而言是有非常明显的缺点的。使用Lua的话需要开发人员掌握Lua和C#,或者将团队中的人员分成C#和Lua小组,适合有足够资源的大型团队。对于中小型团队会很痛苦。
  • 使用C#作为热更语言的话,只要求开发者会C#语言即可,对于Unity项目而言,这种方式是非常高效的,也适合中小型的开发团队。
  • Lua的优势在于解决方案足够成熟,也有很多开发者比起C#作为热更语言,更加熟悉Lua开发。而且借助luajit,在某些情况下的执行效率会非常不错,不过luajit现在的维护情况也不容乐观,对开发者的要求比较高,所以官方还是推荐使用公版Lua进行开发。

2.建立第一个ILRuntime程序

在这里插入图片描述
首先创建一个新项目。(最好使用unity2019及以上版本)
在这里插入图片描述
点击菜单栏的Window-PackageManager打开插件包管理器。
在这里插入图片描述
点击Advanced勾选Show preview packages。
在这里插入图片描述
搜索ILRuntime并安装。
在这里插入图片描述
安装完成之后在上图位置点击Import into Project导入官方示例工程(Demo)。
在这里插入图片描述
导入成功之后会发现Console窗口报错了,这是因为导入的Demo中写了不安全的代码导致的。
在这里插入图片描述
点击Edit-ProjectSettings打开项目设定
在这里插入图片描述
点击Player,在右边OtherSetting下找到Allow unsafe Code这一项,打上勾,报错就消失了。
这是让Unity允许使用不安全的代码。
在这里插入图片描述
报错解决之后,按照上图目录打开导入的HellowWorld场景并运行。
在这里插入图片描述
你会发现,他又报错了,这是因为:
在这里插入图片描述
场景内GameObject上有个脚本HelloWorld,打开它。
在这里插入图片描述
脚本一开始会执行LoadHotFixAssembly方法。(具体的代码分析在下一节)
在这里插入图片描述
上图是LoadHotFixAssembly方法的流程。而报错的原因就是第一步加载StreamingAssets/HotFix_Project.dll时没有找到该文件。解决办法如下:
在这里插入图片描述
鼠标右键导入的Demo中的1.6.4文件夹点击Show in Explorer在资源管理器中打开它。
在这里插入图片描述
依次双击1.6.4-Demo,进入Demo目录。
在这里插入图片描述
看到有两个文件夹在Unity的Project面板里没有显示,这是因为,Unity规定文件夹后加符号’~’,就不会在Unity中显示。
我们双击HotFix_Project~文件夹。
在这里插入图片描述
双击HotFix_Project.sln文件,打开这个热更的项目工程。
在这里插入图片描述
右键HotFix_Project点击生成,编译一个动态链接库。
在这里插入图片描述
在这里插入图片描述

成功生成,这我们的Unity里已经有了HotFix_Project.dll文件。我们回到Unity项目,点击运行。
在这里插入图片描述
这时Unity的Console面板没有报错,并看到Unity控制台窗口出去文字”!!!InstanceClass.StaticFunTest()”,说明我们成功运行了我们的项目。

3.ILRuntime源码分析

在这里插入图片描述
这是HelloWorld.cs的流程图。
我们来分析一下刚刚的HelloWorld脚本:
在这里插入图片描述
首先,这个脚本开启了一段协程运行LoadHotFixAssembly方法。
在这里插入图片描述
这个脚本首先创建了一个AppDomain,Appdomain是一个应用程序域,每个AppDomain都是一个独立的沙盒。
在这里插入图片描述
这里,LoadHotFixAssembly加载streamingAssets文件夹下的HotFix_Project.dll文件,并读取到内存中。appdomain.LoadAssembly(HotFix_Project.dll),将热更dll读取到热更脚本引擎。
在这里插入图片描述
然后调用InitializeILRuntime()方法:初始化ILRuntime脚本引擎。
最后OnHotFixLoaded()方法:执行脚本引擎加载后的逻辑处理。
这就是LoadHotFixAssembly方法干的事。
我们再来看一下OnHotFixLoaded()方法。
在这里插入图片描述
这段代码的意思就是:调用HotFix_Project的项目里的InstanceClass命名空间下的StaticFunTest方法。我们去看一下这个方法:
在这里插入图片描述
在这里插入图片描述
里面只有一个语句意思是:输出”!!!InstanceClass.StaticFunTest()”。
这就是我们刚刚在运行Unity时在Consle面板输出的文字。

4.深入ILRuntime热更新原理

在这里插入图片描述
 通过上面的代码解析我们已经了解到,Unity主工程可以通过appdomain.LoadAssemblyPreobject.dll”)去加载热更新dll。
我们可以把Unity主工程和HotFix_Project.dll叫做两个程序域(AppDomain)。程序域和程序域之间是不能互通的。
 举个例子:网通和电信的网络,走的是两条不同的线路,他们的硬件在物理上是不互通的。那么如果想要网通的用户和电信的用户在一句游戏里能够互相对战,我们就需要一个双线服务器,这个双线服务器就是一个中介桥梁,他把网通的数据发给电信,电信的数据发给网通,这样两边的用户就可以在一局游戏里战斗了。
 所以Unity的主工程的数据类型和热更工程的数据类型是不直接互通的。Unity的主工程的数据类型和热更工程的数据类型要想实现互通的话,就需要实现一些跨域功能。
在这里插入图片描述

  • 跨域委托:需要额外添加适配器或者转换器。例如,主工程中有一些方法,在热更工程中通过一个代理去调用主工程的方法,需要实现跨域委托。(想知道关于跨域委托的实现可以添加老师联系方式)
  • 跨域继承:如果想在热更工程里继承主工程的类/接口,则需要在Unity主工程中实现一个继承适配器并注册。这样热更工程就可以调用继承适配器进行继承。
  • 反射转换:热更工程中的数据类型和C#数据类型是不通用的,所以需要类型映射后使用。
  • CLR重定向:ILRuntime之所以能达到高性能,是因为它会劫持热更工程中可能出现GC的方法调用,它可以进行重定向。我们就有机会将可能产生GC的功能替换成我们自己的实现,从而实现高效能。更多请参见官方文档。
  • CLR绑定:请参见官方文档。(也可添加老师联系方式进行了解)
    在这里插入图片描述
  • ILRuntime借助Mono.Cecil库读取DLL的PE信息(程序的一些基础信息),解析其中所有类型,得到IL汇编码,通过IL解释器执行。
  • 为了得到高性能运算,ILRuntime自己实现了一个脚本栈,通过脚本栈,提高运行效率。
    如果没有脚本栈,C#会将所有的数据类型放在Stack类中,所有数据类型都会作为Object类型存储,产生大量的拆箱和装箱,因此性能会非常低下。(添加老师联系方式,获取VIP课程,在VIP课程中会对此处有详解)
  • ILRuntime使用unsafe代码(指针)以及不会产生GC的内存管理方式(手动分配手动释放),以此来达到高性能。(VIP课程也会对此处代码进行详细分析)
    在这里插入图片描述
  • 如果要对比ILRuntime和Lua的性能,最好亲自去进行测试。测试的话,要在Release模式下进行测试。
  • 使用ILRuntime后,在进行项目打包时,要关闭Development Build选项,不然会增加额外负载,导致性能测试不准确。
  • 避免GC:
     1.最好不要使用ILRuntime跨域调用默认采用反射,或者尽量少用,多用CLR绑定或基于InvocationContext的调用(详细请添加老师的联系方式)
     2.如果你有一些值类型的数据,比如Vector2、Vector3,这些值类型的数据类型,如果直接使用C#的值类型的数据,中间会存在一个数据类型转换,从而产生GC,所以应该基于托管栈重新实现值类型的代码绑定。(详细请添加老师的联系方式)
     3.如果有些频繁调用的方法(比如Update方法)要避免可变参数列表,因为会new数组出来,如果每一帧都去new一个数组,会产生大量GC。
    在这里插入图片描述
    在商业项目中的ILRuntime解决方案:
  • 如果脚本代码是基于MonoBehaviour的话,脚本是不能进行热更的,所以我们需要一个不依赖于MonoBehaviour的代码框架(在老师的皇室战争课程中有教学)
  • 为了避免GC,所以我们要多用CLR绑定,但是如果所有CLR绑定都手写,这个工作量极大,所以要进行自动化CLR绑定生成
  • 与Addressable资源管理和热更系统相结合将会更好提升开发效率。

5.深入ILRuntime热更新原理

在这里插入图片描述
有兴趣的话,可以了解进一步学习的内容,这些内容,有些是公开课,有些事独家的。

  • 在我们的公开课中有介绍过Unity热更新的底层原理,有兴趣的话可以加一下艾莉丝老师领取课程资料。
  • 在我们的课程当中会讲到ILRuntime是如何实现CLR绑定和重定向等高级技术的底层原理的。
  • 在公开课中我也说过,既然IOS系统是不能即时编译的,也就是不能动态分配一块内存给它执行权限,那为什么ILRuntime可以动态加载脚本在IOS平台上动态执行脚本。这个也会在我们课程里讲到。
  • 我们会讲到ILRuntime栈的原理以及如何手写代码实现基于栈的代码绑定。
  • 同时我们还会学习Lua框架和基于Lua框架的热更新解决方案。
  • 在这里插入图片描述
     这是我们的学习路线图。这是老版本的,新版本的路线图可以联系我们老师领取。我们的课程是系统且专业的,从C#到独立游戏开发再到大型网络游戏开发都有。
     我不反对自学,但是自学要花费大量的时间精力去找资源,而且学的可能还不全,加入我们的课程你将会学到最全面的游戏开发知识,比如C#及其底层原理,算法和数据结构,计算机图形学,帧同步技术,客户端服务器的框架,编辑器的扩展等,真的是非常的全面且专业。
    在这里插入图片描述
  • 在加入课程以后老师会帮助你定制专属的学习计划,针对每一位同学的基础和学习目标,一对一的讲解课程中的知识点。整个课程由我亲授,课程辅导也是由我亲自辅导,所以不会有什么助教来忽悠大家。已经加入我们VIP课程的同学,对我们课程都是比较满意的。
  • 老师还会帮助你CodeReview,让你学会代码的规范性,源码的管理,代码的性能,代码的框架等。
  • 我们的课程是提前录制好的,只是为了学习效果我们会进行直播授课。
  • 我们还有两年的一对一服务,在两年内我们会提供优质服务,这两年足以让你从新手成长为一个合格的开发者。
  • 我们还有VIP同学圈和企业内推。
  • 最后我们还有就业和创业指导。
  • 有兴趣的同学请添加艾莉丝老师的QQ,加入我们的VIP课程中来。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值