思考并回答以下问题:
xLua里面有一个热补丁的功能。就是你有的C#代码不用改,就可以加入热更新的功能。
xLua热补丁
为什么叫热补丁呢?已有项目中的C#代码只需要增加一些配置,不用做其他任何调整就可使用上类似热更新的功能。由于和热更新也不同,所以叫热补丁。这也是xLua首创的一项功能。
热补丁的优点有这些:
- 侵入性小,老项目原有代码不做任何调整就可使用。
- 出问题了才用Lua代码来打补丁,这时才会走到lua代码逻辑。运行时影响小,不打补丁基本和原有程序一样。
使用流程
xLua的热补丁使用大体流程如下:
- 添加HOTFIX_ENABLE宏打开该特性(在Unity3D的File-›Build Setting-›Scripting Define Symbols下添加)。编辑器、各手机平台这个宏要分别设置。如果是自动化打包,要注意在代码里用API设置的宏是不生效的,需要在编辑器设置。
(建议平时开发业务代码不打开HOTFIX_ENABLE,只在build手机版本或者要在编译器下开发补丁时打开HOTFIX_ENABLE)
配置热补丁代码,标识要热更新的类型
执行XLua/Generate Code菜单。
编辑器下开发补丁需要手动执行”XLua/Hotfix Inject In Editor”菜单。打印“hotfix inject finish!”或者“had injected!”才算成功,否则会打印错误信息。发布构建时,这个步骤会自动进行。
如果已经打印了“hotfix inject finish!”或者“had injected!”,执行xlua.hotfix仍然报类似“xlua.access, no field __Hitfix0_Update”的错误,要么是该类没配置到Hotfix列表,要么是注入成功后,又触发了编译,覆盖了注入结果。
注意这个过程会用到xLua中的Tools,需要放到和Assets的同级目录
标识要热更新的类型
和之前学到的xLua配置生成代码类似,有两种方式:
方式一:直接在类里头打Hotfix标签(不建议使用,示例代码只是为了方便演示采取这种方式);
方式二:在一个static类的static字段或者属性里头配置一个列表。属性可以用于实现的比较复杂的配置,比如根据Namespace做白名单。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//如果涉及到Assembly-CSharp.dll之外的其它dll,如下代码需要放到Editor目录
public static class HotfixCfg
{
[ ]
public static List‹Type› by_field = new List‹Type›()
{
typeof(HotFixSubClass),
typeof(GenericClass‹›),
};
[ ]
public static List‹Type› by_property
{
get
{
return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
where type.Namespace == "XXXX"
select type).ToList();
}
}
}
热补丁的限制
- 不支持静态构造函数。
- 目前只支持Assets下代码的热补丁,不支持引擎,c#系统库的热补丁。
热补丁Lua API
xlua.hotfix(class, [method_name], fix)
描述 : 注入lua补丁
class : C#类,两种表示方法,CS.Namespace.TypeName或者字符串方式”Namespace.TypeName”,字符串格式和C#的Type.GetType要求一致,如果是内嵌类型(Nested Type)是非Public类型的话,只能用字符串方式表示Namespace.TypeName+NestedTypeName;
method_name : 方法名,可选;
fix : 如果传了method_name,fix将会是一个function,否则通过table提供一组函数。table的组织按key是method_name,value是function的方式。
base(csobj)
描述 : 子类override函数通过base调用父类实现。
csobj : 对象
返回值 : 新对象,可以通过该对象base上的方法
例子:1
2
3
4
5xlua.hotfix(CS.BaseTest, 'Foo', function(self, p)
print('BaseTest', p)
base(self):Foo(p)
end)
util.hotfix_ex(class, method_name, fix)
描述 : xlua.hotfix的增强版本,可以在fix函数里头执行原来的函数,缺点是fix的执行会略慢。
method_name : 方法名;
fix : 用来替换C#方法的lua function。
例子
下面来看个简单的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34using UnityEngine;
using XLua;
[ ]
public class HotfixTest : MonoBehaviour
{
LuaEnv luaenv = new LuaEnv();
private int tick = 0;
// Update is called once per frame
void Update()
{
if (++tick % 50 == 0)
{
Debug.Log("››››››››Update in C#, tick = " + tick);
}
}
void OnGUI()
{
if (GUI.Button(new Rect(10, 10, 300, 80), "Hotfix"))
{
luaenv.DoString(@"
xlua.hotfix(CS.HotfixTest, 'Update', function(self)
self.tick = self.tick + 1
if (self.tick % 50) == 0 then
print('‹‹‹‹‹‹‹‹Update in lua, tick = ' .. self.tick)
end
end)
");
}
}
}
运行这个例子有几步需要注意,其实就是上面学到的热补丁使用流程:
添加 HOTFIX_ENABLE 到 ‘Edit › Project Settings › Player › Other Settings › Scripting Define Symbols’
配置生成代码,这个代码中已经有了
生成代码:执行 ‘XLua › Generate Code’ 菜单,等待Unity编译完成。
注入:执行 ‘XLua › Hotfix Inject In Editor’ 菜单。在编辑器中需要执行,发布时会自动执行。
运行,点击Hotfix按钮查看效果。
这个例子也可以在xLua的XLua\Examples\08_Hotfix的HotfixTest场景直接运行。
总结
xLua的热补丁功能给了需要热更新的项目很大的发挥空间,可以用C#写原有的项目,只用热补丁修复临时的bug,也可以使用lua来开发整个项目。