1:什么是xLua
xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。
2:为什么选择xLua进行热更新
这是因为Lua具有轻量、灵活的特点,可以在几乎任何平台上编译、运行。Unity一般使用C#代码编写游戏逻辑。在打包时,C#会先编译成IL(中间语言),存储到dll(动态链接库)中。在游戏运行时,需要通过JIT(即时编译)将IL解释为机器码。在这期间,会开辟一块内存空间,且要求这块空间可读、可写、可执行。但IOS平台是不允许获取具有可执行权限的内存空间的。因此只能进行全量更新。但Lua是使用C写的脚本语言,在运行时读入Lua代码,在解释时直接使用C代码进行解释,不需要开辟特殊的内存空间,执行解释的是C语言编写的虚拟机。(参考自这篇文章)
原文链接:https://blog.youkuaiyun.com/LWR_Shadow/article/details/127113712
3:xLua的使用
(1)xLua管理器
xLua管理器可以使用单例类实现,在初始化时通过new LuaEnv()新建一个LuaEnv实例化对象, 大G表通LuaEnv.Global。
主要方法有Require执行lua脚本,Tick手动垃圾回收,以及Dispose释放和关闭LuaEnv。
(2)c#加载Lua脚本
重定向加载文件路径 luaEnv.AddLoader(返回值为byte[],参数为ref字符串的委托)。
在设置重定向后,会先去重定向的路径加载lua,找不到再去Resources文件下加载lua 。
(3)c#调用Lua
一:c#获取xlua全局变量
通过 LuaEnv.Global.Get<类型>("变量名")获取。值拷贝。
二:c#获取xlua全局方法
通过 LuaEnv.Global.Get<委托类型>("lua函数名")。
多返回值(out或者ref)LuaEnv.Global.Get<委托类型>("lua函数名",参数列表)。
三:c#获取xLua表映射为list和dic
通过 LuaEnv.Global.Get<List<>/Dic<>>("表名") 获取 和toLua不同的是,属于值拷贝。
四:c#获取xLua表映射为class
通过 LuaEnv.Global.Get<类名>("表名"), 值拷贝。
使用类中方法直接.方法名调用就好。
五:c#获取xLua表映射为接口
引用拷贝,需要添加CSharpCallLua特性,代码生成器会生成接口的实例;需要注意的是:接口的变量需要用公共属性且公共get和set,函数用委托装载。和反射相似,成员变量可多可少 。
(4)Lua调用c#
一: xLua调用c#的class
格式:cs.命名空间.类名。使用()模拟new实例对象。
二: xLua调用c#的enum
跟调用类一致,cs.命名空间.枚举.枚举值
int转为枚举 枚举.__CastForm(数值)
string转为枚举 枚举.__CastForm(字符串)
三 :xLua调用c#数组
可以通过类来调用,访问方法一致
xlua创建数组固定格式CS.System.Array.CreateInstance(typeof(类型),长度) 下标从0开始
四 :xLua调用List和Dic
可以通过类来调用
List:下标从0开始,创建List固定格式CS.System.Collections.Generic.List(CS.命名空间.类名)。得到的返回值设result,只是声明了还没实例,需要result()实例
Dic:创建Dic固定格式CS.System.Collections.Generic.Dictionary(CS.命名空间.类名,CS.命名空间.类名)
字典需注意的是如果key为字符串,则需要使用get_Item("key名")和set_Item("key名")访问字典值,其他类型可以使用[key]访问。
五: xLua调用c#函数
1:拓展方法需要在拓展静态类加上LuaCallCSharp特性
2:xLua支持重载,但是不支持精度重载,如果需要使用精度重载要使用反射机制,最后将methodInfo通过xlua.tofunction(methodInfo)()访问
3:ref和out,ref参数不能省略,out参数可以省略也可以用nil占位
4:xLua仅仅支持有参有约束泛型,如果要使用有参无约束泛型,要使用反射,通过xlua.get_generic_method(CS.命名空间.类名,"方法名")得出来的设fun,然后fun(类型)指定泛型类型,返回的设fun_r,最后通过fun_r(参数列表)使用
六:xLua调用c#委托和事件
委托:可以直接使用.del()执行,在添加和删除方法时使用=+,第一次添加时要使用=。
事件:通过 事件名("+/-",方法名)来添加和删除方法,碍于事件特性,要在c#中编写执行和清空逻辑
七:xLua调用c#协程
xLua提供了关键字如coroutine.yield(WaitForSeconds(1))表示c#的yield return new WaitForSeconds(1)。
在xLua中编写好协程。通过(执行xlua.util脚本获取xlua写好的工具表),使用util.cs_generator(xlua写好的协程方法)转为可以供c#使用的协程.然后通过c#的mono类的.StartCoroutine(协程名)执行和StopCoroutine(协程名)关闭
4:特别的
1:xLua对c#的二维数组不能使用[][]访问,要通过.GetLength(0/1)获取行、列数,通过.GetValue(x,y)获取对应的值
2:nil和null无法直接比较,要么在c#中执行比较要么在lua中执行比较
3:可以新建静态类,在其中添加type数组逐一给系统类如UnityAction添加特性
4:xLua调用c#是大部分基于反射机制,性能可能有额外消耗,可以在尽量涉及的类中添加属性,生成代码,可能有助于优化反射性能?