快捷搜索:

【程序猿】腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)

程序猿】腾讯开源手游热更新方案:Unity3D下的XLua术内幕(一)

2017-01-05 18:14 来源:腾讯游戏学院 腾讯 /

原标题:【程序猿】腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)

目前Unity下的热更新方案有不少,这些方案都要求要热更新的地方一开始就得用脚本来实现,这带来一些问题:

1、接入成本高,有的项目已经用C#写完了,这时要接入需要把需要热更的地方用脚本重新实现;

2、即使一开始就接入了,也存在同时用两种语言开发难度较大的问题,有些项目只是想fix下bug而已,却被迫使用两种语言开发,明显代价有点大;

3、脚本性能不如C#;

对于双语编程的问题,有人尝试通过把C#翻译成脚本来解决(js,lua都见过)。这种翻译往往在C#语法支持上都不完备,而且,性能问题仍然未解决,甚至更严重(除了脚本本身比C#差之外,自动翻译性能会高效?我持保留态度)。

反观Unity之外有不少方案,比如ios下的jspatch,android下的tinker等,并没这约束。以jspatch为例,它支持把一个oc函数替换为js实现,平时开发可以只写oc,只有出现bug,才需要写个js去fix。

把这两个方案应用到Unity技术上可能可以行得通,但问题是jspatch是用来修复oc,android是修复java的,难道要把逻辑在ios下用oc写一份,android下用java写一份,然后编辑器又另外一份?这在需求急剧变化的游戏领域显然是不现实的。

Unity下的热补丁实现也有,但目前看到的方案,都不支持iOS,由于审核制度的存在,iOS热更才是硬需求,一切不支持iOS的热更方案都是耍流氓!

好吧,重头戏来了,xLua最新的热补丁技术比较完美的解决了上面的问题!等等,不是说好了忘掉lua,怎么说起xLua了?好吧,至少项目组大多数人不需要懂Lua,有一个就可以了,这人大多数时间也不用写Lua,出了线上问题才需要。

xLua热补丁技术支持在线把一个C#(方法,属性,事件等等)实现替换成Lua实现。这意味着你可以:

1、开发只用C#;

2、运行也是C#,性能可以秒杀lua;

3、出问题了才用Lua来改掉C#出问题的部位,替换甚至做到不用重启游戏;

用完即走,是小龙哥对一个好工具的定义,xLua这个特性也如此:没问题的时候你感觉不到它的存在,出了问题才需要它来救场。

极其简单的统一接入方式

在启动的地方加入几行代码即可:

【程序猿】腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)

好,你的应用就有了热补丁的能力了,没有hotfix.lua(名字你可以安装你的需要改)时,什么事情都不干,自然也没开销。

你需要在可能需要热更新的类型打上[Hotfix]标签即可(打了标签的类有极其轻微的性能损失,后面会分析)。

一个API打补丁

通过某种方式下载了hotfix.lua,hotfix.lua就是修复代码。

先看简单示例:

【程序猿】腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)

上述代码把C#的HotfixTest类(继承于MonoBehaviour)的Update函数替换成lua的实现。相关API就一个:

xlua.hotfix(class,[method_name], fix)

class是C#的类名,method_name可选,如果写了就替换某函数,没有就是替换类,fix如果给了method_name就提供个函数,没给就通过table提供一组函数。

lua函数的实参,以及属性,事件这些的修复,可以看详细指南。

Stateless和Stateful

打Hotfix标签时,默认是Stateless方式,你也可以选Stateful方式,我们先说区别,再说使用场景。

Stateless方式是指用Lua对成员函数修复时,C#对象直接透传给作为Lua函数的第一个参数。

Stateful方式下你可以在Lua的构造函数返回一个table,然后后续成员函数调用会把这个table给传递过去。

Stateless比较适合无状态的类,有状态的话,你得通过反射去操作私有成员,也没法新增状态(field)。Stateless有个好处,可以运行的任意时刻执行替换。

Stateful的代价是会在类增加一个LuaTable类型的字段(中间层面增加,不会改源代码)。但这种方式是适用性更广,比如你不想要lua状态,可以在构造函数拦截那返回空。而且操作状态性能比反射操作C#私有变量要好,也可以随意新增任意的状态信息。缺点是,执行成员函数之前就new好的对象,接收到的状态会是空,所以需要重启,在一开始就执行替换。

两条指令的性能开销

热补丁基本原理非常简单,所以其性能、内存、安装包影响一目了然。

xLua会在C#编译成il后插入一个处理,该处理会从il层面为每个打了Hotfix标签的类型的函数开头加入几个il指令,如果用C#描述是这样的:

加il指令前:

【程序猿】腾讯开源手游热更新方案:Unity3D下的XLua技术内幕(一)

您可能还会对下面的文章感兴趣: