一. xlua简介
xlua 是由腾讯维护的一个开源项目,除了常规的Lua绑定之外,还有一个比较有特色的功能就是代码热补丁。非常适合前期没有规划使用Lua进行 逻辑开发,后期又需要在iOS这种平台获得代码热更新能力的项目。
刚开始学习使用xlua,主要实现原理暂时还未进行深究,研究过后将会在之后的内容里补上。这里先祭上官方的一张图来简单描述一下:
第一,当然是将xlua添加到我们的工程里,在github上下载xlua之后,将 xlua-master/Assets下的内容拷贝到我们的工程里,因为之后制作热更新的时候需要使用tools文件夹下的XLuaHotfixInject.exe 文件,所以我这边直接将tools文件也整个拷贝到工程里,在真实的项目里大家根据需求有选择的拷贝就好。另外有一点需要注意的是,全拷贝tools文件夹下的内容到工程里的话,Unity会报出重复定义的错误:
此时,将tools里的 System.Core.dll 删除就可以了。
第二,在BuildSettings里添加两个宏:
HOTFIX_ENABLE:开启热更新特性,编辑器,各手机平台需要手动单独设置,如果是自动化打包,要注意在代码里用API设置的宏是不生效的,需要在编辑器里设置。
INJECT_WITHOUT_TOOL:采用内嵌到编辑器的方式注入。添加了该宏之后,在菜单栏XLUA里才能够进行【Hotfix inject in Editor】的操作;在构建手机包的时候这个步骤会在构建时自动进行,编辑器模式下开发补丁需要手动执行Hotfix inject in Editor进行注入。
定义INJECT_WITHOUT_TOOL宏后,热补丁特性依赖Cecil,添加HOTFIX_ENABLE宏之后,可能会报找不到Cecil。这时你需要到Unity安装目录下找到Mono.Cecil.dll,Mono.Cecil.Pdb.dll,Mono.Cecil.Mdb.dll,拷贝到项目里头。
注意:如果你的Unity安装目录没有Mono.Cecil.Pdb.dll,Mono.Cecil.Mdb.dll(往往是一些老版本),那就只拷贝Mono.Cecil.dll(你从别的版本的Unity拷贝一套可能会导致编辑器不稳定),这时你需要定义HOTFIX_SYMBOLS_DISABLE,
这会导致C#代码没法调试以及Log的栈源文件及行号错乱(所以赶紧升级Unity)。
以上两个宏若是不开启,或者在没有成功进行Hotfix inject in Editor操作直接运行的话,系统会抛出 LuaException: xlua.access, no field __Hotfix0_hotfix
第三, 对需要热更的代码部分添加[Hotfix]标签,这样xLua就知道这个类或者方法等可能会有热更新的需求。
第四,Unity侧的调用:
第五,Lua侧(蛮牛不能插入lua的代码,看起来很不方便啊):
HotfixTest_easy = {}
function HotfixTest_easy.HotFixEasy()
print("xxxxxxx lua cast")
end;
xlua.private_accessible(CS.HotfixTest_easy)
xlua.hotfix(CS.HotfixTest_easy,'HotFixEasy',HotfixTest_easy.HotFixEasy)
几个重要的xlua 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的方式。
xlua.private_accessible(class)
描述 : 让一个类的私有字段,属性,方法等可用
class : 同xlua.hotfix的class参数
util.hotfix_ex(class, method_name, fix)
描述 : xlua.hotfix的增强版本,可以在fix函数里头执行原来的函数,缺点是fix的执行会略慢。
method_name : 方法名;
fix : 用来替换C#方法的lua function。
第六,执行xlua/Generate Code--->执行XLua/Hotfix Inject In Editor,其中,执行后者的时候,因为XLUA源代码里需要找到XLuaHotfixInject.exe(tools里)才能运行,需要收到修改代码里找到该文件的路径(反正为了运行我暂时先改了)
第七,运行。
运行结果:
当热更新目录(我这里为了方便暂时放在Resource文件夹下)里不存在指定的文件时,则执行C#定义的方法:
当存在指定的文件时,则进行热更新的操作:
以上仅仅用一个简单的例子给大家掩饰了使用xlua进行代码热更新的流程,还有很多xlua强大的功能没有涉及到,本文也是一个抛砖引玉,最主要的还是记录我自己学习过程,我没有弟子来记录我平时的言行语录,我就自己来!
xlua 是由腾讯维护的一个开源项目,除了常规的Lua绑定之外,还有一个比较有特色的功能就是代码热补丁。非常适合前期没有规划使用Lua进行 逻辑开发,后期又需要在iOS这种平台获得代码热更新能力的项目。
刚开始学习使用xlua,主要实现原理暂时还未进行深究,研究过后将会在之后的内容里补上。这里先祭上官方的一张图来简单描述一下:
传送门系列:
官网:
配置文档:
官方FAQ:
代码生成引擎:
Lua5.3官方手册:
关于xlua和lua的基础知识,在官网上和其他一些教程里都有详细的描述,我这边就不贴了,这次主要说一下我在学习使用xlua时遇到的
问题已经需要注意的一些地方,最后奉上自己使用Unity和xlua交互制作的一个小程序和一个xlua热更新的例子。好的,那我就先从热更新开始啦~
二. xlua热更新
第一,当然是将xlua添加到我们的工程里,在github上下载xlua之后,将 xlua-master/Assets下的内容拷贝到我们的工程里,因为之后制作热更新的时候需要使用tools文件夹下的XLuaHotfixInject.exe 文件,所以我这边直接将tools文件也整个拷贝到工程里,在真实的项目里大家根据需求有选择的拷贝就好。另外有一点需要注意的是,全拷贝tools文件夹下的内容到工程里的话,Unity会报出重复定义的错误:
此时,将tools里的 System.Core.dll 删除就可以了。
第二,在BuildSettings里添加两个宏:
HOTFIX_ENABLE:开启热更新特性,编辑器,各手机平台需要手动单独设置,如果是自动化打包,要注意在代码里用API设置的宏是不生效的,需要在编辑器里设置。
INJECT_WITHOUT_TOOL:采用内嵌到编辑器的方式注入。添加了该宏之后,在菜单栏XLUA里才能够进行【Hotfix inject in Editor】的操作;在构建手机包的时候这个步骤会在构建时自动进行,编辑器模式下开发补丁需要手动执行Hotfix inject in Editor进行注入。
定义INJECT_WITHOUT_TOOL宏后,热补丁特性依赖Cecil,添加HOTFIX_ENABLE宏之后,可能会报找不到Cecil。这时你需要到Unity安装目录下找到Mono.Cecil.dll,Mono.Cecil.Pdb.dll,Mono.Cecil.Mdb.dll,拷贝到项目里头。
注意:如果你的Unity安装目录没有Mono.Cecil.Pdb.dll,Mono.Cecil.Mdb.dll(往往是一些老版本),那就只拷贝Mono.Cecil.dll(你从别的版本的Unity拷贝一套可能会导致编辑器不稳定),这时你需要定义HOTFIX_SYMBOLS_DISABLE,
这会导致C#代码没法调试以及Log的栈源文件及行号错乱(所以赶紧升级Unity)。
以上两个宏若是不开启,或者在没有成功进行Hotfix inject in Editor操作直接运行的话,系统会抛出 LuaException: xlua.access, no field __Hotfix0_hotfix
第三, 对需要热更的代码部分添加[Hotfix]标签,这样xLua就知道这个类或者方法等可能会有热更新的需求。
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
|
using
UnityEngine;
using
System.Collections;
using
XLua;
[Hotfix]
public
class
HotfixTest_easy{
public
void
HotFixEasy()
{
Debug.Log(
"Unity调用"
);
}
}
|
第四,Unity侧的调用:
[C#]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
using
UnityEngine;
using
System.Collections;
using
XLua;
public
class
HotFixMono : MonoBehaviour {
XLua.LuaEnv m_kLuaEnv =
null
;
private
HotfixTest_easy fixEasy =
null
;
// Use this for initialization
private
bool
isShow =
false
;
void
Start () {
//代码热更步骤
m_kLuaEnv =
new
LuaEnv();
//该变量最好保证全局就此一个
//1.查找指定路径下lua热更文件
TextAsset txt = Resources.Load(
"HotfixTest_easy.lua"
)
as
TextAsset;
//2.如果存在lua热更文件,则执行lua文件的执行,否则不执行(也就是说,到底是读取C#本地代码还是LUA热更代码是由我们自己控制,xlua框架并不提供识别机制,这只是我现在的个人理解,如果不正确,请一定要告知我!)
if
(txt !=
null
)
{
m_kLuaEnv.DoString(txt.text,
"HotfixTest_easy.HotFixEasy"
);
//这个方式是替换指定的方法
}
fixEasy =
new
HotfixTest_easy();
}
// Update is called once per frame
void
Update()
{
if
(!isShow)
{
isShow =
true
;
fixEasy.HotFixEasy();
}
}
}
|
第五,Lua侧(蛮牛不能插入lua的代码,看起来很不方便啊):
HotfixTest_easy = {}
function HotfixTest_easy.HotFixEasy()
print("xxxxxxx lua cast")
end;
xlua.private_accessible(CS.HotfixTest_easy)
xlua.hotfix(CS.HotfixTest_easy,'HotFixEasy',HotfixTest_easy.HotFixEasy)
几个重要的xlua 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的方式。
xlua.private_accessible(class)
描述 : 让一个类的私有字段,属性,方法等可用
class : 同xlua.hotfix的class参数
util.hotfix_ex(class, method_name, fix)
描述 : xlua.hotfix的增强版本,可以在fix函数里头执行原来的函数,缺点是fix的执行会略慢。
method_name : 方法名;
fix : 用来替换C#方法的lua function。
第六,执行xlua/Generate Code--->执行XLua/Hotfix Inject In Editor,其中,执行后者的时候,因为XLUA源代码里需要找到XLuaHotfixInject.exe(tools里)才能运行,需要收到修改代码里找到该文件的路径(反正为了运行我暂时先改了)
第七,运行。
运行结果:
当热更新目录(我这里为了方便暂时放在Resource文件夹下)里不存在指定的文件时,则执行C#定义的方法:
当存在指定的文件时,则进行热更新的操作:
以上仅仅用一个简单的例子给大家掩饰了使用xlua进行代码热更新的流程,还有很多xlua强大的功能没有涉及到,本文也是一个抛砖引玉,最主要的还是记录我自己学习过程,我没有弟子来记录我平时的言行语录,我就自己来!