Unity热更方案汇总
http://www.manew.com/thread-114496-1-1.html
谈到目前的代码热更方案:没什么特别的要求
<ignore_js_op>
toLua(效率比sLua高)
打算以传统方式更新,热更仅仅用于紧急更新 / 希望战斗等性能敏感部分也能更新
xLua(性能在Lua系列中一般,但额外支持HotFix,可以更多使用C#代码)
基本上普通的项目也就只能用这两,也就是只有Lua一条路可走。
然而,由于Lua自身缺少编译期间语法检查以及缺乏必要的语言特性,在熟练的开发者手里开发效率和健壮性其实是不如其他强类型语言的。
——这点可能会有异议,我只能这么讲:使用强类型语言的程序员都会有一些增加开发效率和代码健壮性的“小技巧”,但这些技巧必须依附于语言特性以及某些只在强类型语言上才能使用的IDE功能。而且这样做的优势更多体现在项目的后期,也和团队的协作模式有关,没接触到的人可能确实无法理解。
一些人可能会觉得lua比C#更好用,但在另一些人手里C#也确确实实能够比lua提供更多的开发效率,保证更低的BUG概率,你不能因为自己“不知道,不用”,而认为他们的需求不存在。
现有的可使用强类型语言的代替方案如下:
- 使用ILRuntime解释器(C#解释器)
- 使用JS解释器(V8),并且使用TypeScript
- 依然使用Lua解释器,但是使用一门强类型语言编程,并翻译至Lua
ILRuntime解释器
按一般的思路来看,用ILRuntime是比较正统的解决方案,如果由Unity官方来推动代码热更的话恐怕就是这个,毕竟没有哪个语言在提供代码热更的方案的时候,会主动换成另外一个脚本语言(点击此处了解)
而且相比其他更冷门的解决方案,ILRuntime还是有一些实际产品的。
优点应该无需臃述,现在单说缺点:
- 慢
借用这位老兄的测试结果Unity中SLua、Tolua、XLua和ILRuntime效率评测 - CSDN博客。
在可使用JIT的安卓环境下,ILRuntime其实比lua拥有更好的性能。但是在不能使用JIT的IOS环境下,虽然在普通的API调用方面和lua差距不大,但是在纯粹的简单数值计算,循环,数组存取上,确实和lua有着非常大的差距(下图的最后两个Test)
<ignore_js_op>
虽然这个测试结果看上去很严重,但毕竟Test9是这样的测试代码
<ignore_js_op>
用来作为慢18倍的依据恐怕并不合适。
而在Test8里
<ignore_js_op>
只是循环内多了几个简单计算,两者之间的差距就缩小了很多(仅3倍)。
由于ILRuntime在调用C#API时效率比Lua更高(无需类型转换),综合判断,在实际的项目里很可能差距也就2,3倍,这并非不能接受的。在安卓JIT下更是可以和Lua拉平。
因为和外部的非热更代码使用的是同一语言,穿透调用性能较高,将性能敏感的代码移动到非热更区域会比Lua更加容易,细心处理搞不好性能还会更高。
如果实在担心ILRuntime的性能问题。其实可以去查一下python和lua的性能对比——ILRuntime还真不一定比“一切皆对象”的python慢。
而网易的手游基本都是python,这个信息对说服老板使用此方案应该会有比较大的帮助。
此外,还有位老兄仿造xlua写了一个基于ILRuntime的HotFix方案(点击此处查看)
这样给予了这个方案更大的使用灵活性,可以选择新版本使用最高效的il2cpp代码,而旧版本通过热更部分使用效率较低的ILRuntime代码。这样虽然ILRuntime部分比lua慢,但是占比更大的il2cpp部分则比lua快,整体上反而比lua方案效率增加了。
而且不同与xLua,HotFix和正常更新并存的方案并不需要两套代码,实现成本其实不高。
(但要注意这库是个新库,虽然ILRuntime本身是经过验证的方案,但他新加这套东西不好说有没有问题,想用C# HotFix就要承担这个风险。)
TypeScript
有人用,但我不了解,跳过吧。
由强类型语言翻译至Lua
最理想的做法,是直接将C#翻译成Lua。(点击此处查看)
但据使用过的人评价,这个库效果并不稳妥。没用过,所以此言论仅供参考。
这里要说的是另一个转换方案(点击此处查看)
HaXe这个语言应该大部分人都没听说过,它本身就是一个“翻译成其他语言”以实现跨平台的语言,所以没有厂商背书也没有社区影响,因为这个理由一直很冷。
但是在现在这个状况下,还真没有比这个更好的选择了。
首先HaXe生成lua在coscos时代还真有项目这么用,它在生成lua代码这方面的能力起码被证实了。语言本身是ECMA系的,没有学习难度,大概是个TS+AS的混合体,包括类型推断等现代语言特性,至少是不比C#差的。唯一缺少的是方法重载,但是有不定向的参数默认值作为代替。
除此之外还有一些奇怪的语法糖特性,但是可以不用了解。
虽然需要学习新语言,但毕竟它没有自己的标准库,长得也和现有的语言差不多,其实是没啥学习难度的。
事实上也没有使用风险,因为它其实就是一个广义的lua编辑器,最后输出到Unity工程目录的只有一个lua文件,可以搭配其他lua方案使用。
此外,它也支持输出成C#源文件,也可以方便的把性能敏感代码转移到非热更部分。(点击此处查看)
不过Haxe直接用到Unity上还需要稍微做些工作。因为HaXe是强类型语言,你必须生成一组桥文件才能让它调用Unity的API,和Lua需要生成的C#类桥文件差不多。这个库给了生成的工具。
另外带了几个lua文件桥接了lua的一些功能(比如说协程)
HaXe的桥文件,实质就是指示翻译器在翻译成目标语言的途中让某些代码保持原样,顺带实现代码提示。学会这个用法后,就可以方便地写出自己的扩展,不用担心和其他语言的通信难度问题。https://haxe.org/manual/lf-externs.html。
这个库也是前天才创建的新库,但实际上主要是个示例工程,因为HaXe其实本来就可以直接用在Unity+???Lua上的。
现在也基本能用了,至少在我看来,HaXe这个方案是目前成本最低的,最安全的“干掉天杀的Lua”的办法。
知乎@flashyiyi