题记
我们知道,在Unity游戏项目中为了实现项目热更,大多数采用lua进行开发。但是在lua并非Unity原生支持的语言,所以在一些情况下还是必须要使用CSharp进行开发(如开发一些组件等)。然而CSharp一旦出错就无法及时热更修复。需要重新出包,测试,提审,上架等。为了解决CSharp的更新问题,Xlua提出了热修复
的解决方案。参考如下官方文档。
官方文档:https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md
约束
- 不支持静态构造方法
- 只支持Assets目录下代码热更。
使用方法
添加宏HOTFIX_ENABLE
File->Build Setting->Player Settings->Other Setting->Scripting Define Symbols
两种标识热更新的类型
- 标识要热更新的类型
需要提前给需要热更的方法加[Hotfix]
标签。(所以很鸡肋,官方也不推荐使用)。PASS。 - 在一个static类的static字段或者属性里头配置一个列表。
利用反射进行标记。官方推荐此方法。如下参考。!!注意,高版本Unity需要把配置文件放Editor目录下!!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 热更名单
[ ]
public static List<Type> HotfixList
{
get
{
string[] allowNamespaces = { };
string[] allowClassNoNamespace =
{
"XLuaManager",
};
return (from type in Assembly.Load("Assembly-CSharp").GetTypes()
where allowNamespaces.Contains(type.Namespace) ||
(allowClassNoNamespace.Contains(type.Name) && string.IsNullOrEmpty(type.Namespace))
select type).ToList();
}
}
打补丁
xlua可以用lua函数替换C#的构造函数,函数,属性,事件的替换。lua实现都是函数,比如属性对于一个getter函数和一个setter函数,事件对应一个add函数和一个remove函数。
假设有如下CSharp方法,在实际用用中有问题,需要对它进行修复:
1
2
3
4
5
6
7public class XLuaManager
{
public static void TestHotFix()
{
Debug.LogError("Hotfix error");
}
}修复代码如下:(创建补丁文件HotfixTest.lua)
1
2
3xlua.hotfix(CS.XLuaManager, "TestHotFix",function()
print('xlua hotfix is ready')
end)将补丁名称放到一个存放补丁的列表中。
在lua执行的入口,假设叫
main.lua
吧。Main中执行补丁列表中的lua方法。1
2
3
4
5
6
7
8
9-- 这里将lua补丁放到PatchesList文件中,集中管理
-- 调用补丁
local patchs = require("PatchesList")
for _, item in pairs(patchs) do
require(item)
print("Lua patch invoked: " .. item)
end
效果如下:
热修复的原理
- 标记需要热更的类。xlua会在il层注入代码如下形式:
1
2
3
4[ ]
public class A{
int Add(int a, int b) return a+b;
}1
2
3
4
5
6
7
8
9public class A{
static Func<object, int, int, int> hotfix_Add = null;
int Add(int a, int b)
{
if(hotfix_Add!=null)
return hotfix_Add(this, a, b);
return a + b;
}
}