Xlua学习

一. xlua简介
   xlua 是由腾讯维护的一个开源项目,除了常规的Lua绑定之外,还有一个比较有特色的功能就是代码热补丁。非常适合前期没有规划使用Lua进行 逻辑开发,后期又需要在iOS这种平台获得代码热更新能力的项目。
    刚开始学习使用xlua,主要实现原理暂时还未进行深究,研究过后将会在之后的内容里补上。这里先祭上官方的一张图来简单描述一下:
Xlua学习_第1张图片 

传送门系列:

官网:
https://github.com/Tencent/xLua
配置文档:
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/hotfix.md
官方FAQ:
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/faq.md
代码生成引擎:
https://github.com/Tencent/xLua/blob/master/Assets/XLua/Doc/custom_generate.md
Lua5.3官方手册:
https://www.lua.org/manual/5.3/manual.html

  关于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学习_第2张图片 
Xlua学习_第3张图片 

当存在指定的文件时,则进行热更新的操作:
Xlua学习_第4张图片 
Xlua学习_第5张图片 

你可能感兴趣的:(热更)