最近huatuo(华佗)热更新解决方案火爆了unity开发圈,起初我觉得热更新嘛,不就是内置一个脚本解释器+脚本语言开发,如xLua, ILRuntime, puerts。Huatuo又能玩出什么花样,凭什么会这么NB,引起了那么多程序员的关注与称赞呢?带着这些问题我详细的看了huatuo的资料,阅读了示例项目+huatuo源码,我也瞬间成了一位”佗粉”。接下来更新一系列的文字教程+视频教程来详细的讲解huatuo热更新。
对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。
要掌握huatuo热更新,我们先搞懂一些底层的概念与原理,搞懂这些是掌握huatuo的关键。本节我将从以下3个方面来详细的讲解huatuo热更新解决方案:
(1) il2cpp是什么? AOT是什么?
(2) huatuo热更新的技术原理;
(3) huatuo热更方案的革命性优势;
il2cpp是什么? AOT是什么?
在说il2cpp之前,先说说mono, 在mono之前,C#虽然很好,但是只在windows家族平台上使用,就这点C#与Java就无法比。于是微软公司向ECMA申请将C#作为一种标准。在2001年12月,ECMA发布了ECMA-334 C#语言规范。C#在2003年成为一个ISO标准(ISO/IEC 23270)。意味着只要你遵守CLI(Common Language Infrastructure),第三方可以将任何一种语言实现到.Net平台之上。有了CLI的标准,Mono就诞生了, 该项目的目标是创建一系列符合ECMA标准(Ecma-334和Ecma-335)的.NET工具,包括C#编译器和通用语言架构。与微软的.NET Framework(共通语言运行平台)不同,Mono项目不仅可以运行于Windows系统上,还可以运行于Linux,FreeBSD,Unix,OS X和Solaris,甚至一些游戏平台,例如:Playstation 3,Wii或XBox 360之上。Mono使得C#这门语言相对于微软的.Net有了很好的跨平台能力。
.Net Framework运行时库Mono使用自己的Mono VM。 加上C#本身快速友好的开发能力,最终使得Unity团队在创建之初就决定将Mono,C#作为其核心。
接下来引出重要的一个概念”IL“。IL的全称是 Intermediate Language,很多时候还会看到CIL(Common Intermediate Language,特指在.Net平台下的IL标准)。在Unity中,IL和CIL表示的是同一个东西:它是一种属于通用语言架构和.NET框架的低阶(lowest-level)的编程语言。将.NET框架的语言编译成CIL,然后汇编成字节码。CIL类似一个面向对象的汇编语言,并且它是完全基于堆栈的,它运行在.net虚拟机上。
CLI标准出来后,又出现一个项目:IL2CPP,把IL转成静态的c++代码文件,由本地编译器编译成二进制机器指令。由于C#这样的高级语言都有垃圾回收等机制,所以IL转成静态的c++代码后,还有一个IL2CPP的runtime(IL2CPP VM)用来支撑这些高级语言特性。通过IL2CPP技术,我们IL代码转成本地机器码,获得很好的性能。Unity也采用了这个技术,用unity开发的C#代码可以通过.net 转成IL代码,再通过IL2CPP转成静态c++文件,然后编译成本地机器码运行。为什么Unity采用IL2CPP呢?主要原因有:
a:Mono VM在各个平台移植,维护非常耗时,有时甚至不可能完成。
b: Mono版本授权受限, 换IL2CPP,IL2CPP VM这套完全自己开发的组件,就解决了授权问题。
c: 提高运行效率,换成IL2CPP以后,程序编译成了硬件目标机器指令,运行效率提升1.5-2.0倍。
Unity基于IL2CPP 的架构原理,如图1.1-1所示:
图1.1-1 Unity IL2CPP 运行示意图
最后一个概念AOT(Ahead of time),AOT技术指的是将高级开发语言直接转成传统的编译型编程语言(如C/C++),再编译成机器指令代码在硬件上运行。IL2CPP可以成为AOT技术。
huatuo热更新的技术原理
铺垫完IL2CPP,AOT等概念后,接下来就来说huatuo了。由图1.1-1可知Unity最终打包运行为:AOT(本地机器指令执行)+, IL2CPP VM(提供基础服务支撑,如gc)。对于IL2CPP 底层运行模式而言,运行的时候是数据内存对象+代码机器指令两个部分。huatuo做热更就是扩展了IL2CPP VM的服务,让它在使用原来数据内存对象的情况下,扩展了解释执行IL代码的功能(注意这里的使用”原来数据内存对象”很重要)。让IL2CPP的运行模式变为: 数据内存对象+AOT代码机器指令+Interpreter IL指令解释执行的3个部分。huatuo做热更的时候,我们只需要利用Unity ADF(asmdef, 程序集定义文件)的机制,让Unity对某一部分单独编译出一个IL指令的.dll。热更时,IL2CPP_huatuo就可以装载IL指令.dll, 由IL2CPP_huatuo来解释执行。这样AOT模式+huatuo IL指令解释执行 (Interpreter)让huatuo能具备热更新的功能。同时huatuo解释执行使用的是原来AOT的数据内存对象,所以huatuo热更新不会有其它热更新方案需要的接口导出,跨域调用等一系列问题。让开发者在不用做任何特殊处理的情况下,直接使用普通的unity开发技术能做到热更新。由于可以直接使用AOT的数据内存对象,内存占用,性能都会更好。有了这些优势(不用做任何代码上的处理就能实现热更),难怪Unity开发者都欢呼雀跃,因为他们终于能丢掉xLua, ILRuntime又笨又重的壳,直接从底层解决问题。所以我认为未来的huatuo会成为Unity热更的主流方案。
huatuo热更的革命性优势
分析完原理后,我们来看下huatuo的革命性优势:
huatuo第1个优势是基于AOT(本地机器代码执行)+Interpreter (IL解释执行)使用同一个内存数据对象,没有跨域访问的问题。我们来拿xLua或ILRuntime热更方案来举例,这些方案都有一条原则,尽量减少与Unity C#层的交互,但是这种交互又避免不了而且量大,比如我们要在逻辑热更代码里面访问 Unity C#的GameObject对象数据,最终在运行的时候,GameObject 会在AOT模式下的原生内存数据结构对象。由于xLua或ILRuntime有自己的虚拟机,所以不能直接访问原生GameObject数据对象,往往要把访问里面的数据包装成函数,这样性能开销就大大的增加了。而huatuo是在IL2CPP模式下的解释执行,直接可以访问原生的数据对象。
huatuo第2个优势是我们的逻辑代码更新后(1.0版本到2.0版本),如果你发布新版本2.0(重新安装新版本的app),可以直接把更新的逻辑,直接使用AOT编译出来,不用解释执行,从而获得AOT的性能。而基于xLua, ILRuntime的热更方案开发的代码(1.0版本到2.0版本),用户即使重新安装2.0客户端后,还是解释执行,新版本的性能无法达到AOT的性能级别。
huatuo 第3个好处是相比传统的Lua或ILRuntime热更,他能更新任意部分的代码。不用像Lua或ILRuntime一样,分热更代码+框架代码,框架代码有bug还不能热更。
有了这些革命性的优势,你没有理由不关注+使用huatuo。