Xlua学习笔记(Lua调用C#及踩坑)
XLua是目前国内使用较多的热更新框架(可能是有腾讯加持), Xlua同时也提供了Lua调用C#的能力,其实Lua调用C#的场景更多,要想实现热更新,很多控制逻辑都得写在Lua里,这篇文章主要是记录了Lua如何调用C#,以及踩过的一些坑。
在Lua中new C#对象
例如创建GameObject
1print("Lua call C# start...")
2CS.UnityEngine.GameObject()
3-- 指定GameObject的名称
4CS.UnityEngine.GameObject("NewByLua")
Lua访问静态属性、静态方法
记得最好设置本地Local变量,提高性能
1创建对象:
2
3local newGo = CS.UnityEngine.GameObject();
4
5local newGo = CS.UnityEngine.GameObject('name')
6
7访问静态属性:
8
9CS.UnityEngine.Time.deltaTime
10
11CS.UnityEngine.Time.timeScale = 0.5
12
13访问静态方法:
14
15CS.UnityEngine.GameObject.Find('name')
小技巧:如果有一些需要经常访问的类,可以用局部变量引用后,通过局部变量进行访问,可以提高性能
Lua中访问C#成员变量和方法
访问成员属性:.
运算符
访问成员方法:.
运算符或 :
语法糖
1local cameraComponent = camera.GetComponent(camera, "Camera")
2
3local cameraComponent = camera:GetComponent("Camera")
注意:在Lua中没有this关键字,所以如果使用 .
,则需要在方法中手动传递对象本身;如果使用:
则不需要
带有结构体的参数的方法
在lua端定义一个表去映射结构体:
1public struct MyStruct
2{
3 public string x;
4 public string y;
5}
6
7public void CSharpFunc(MyStruct p)
8{
9 Debug.Log(p.x);
10 Debug.Log(p.y);
11}
12
13--lua
14myStructTable={x="C#",y="lua"}
15obj:CSharpFunc(myStructTable)
调用C#泛型方法
lua中不支持C#的泛型方法,但可以使用扩展方法来调用
1public void GenericMethod<T>()
2{
3 Debug.Log("GenericMethod<" + typeof(T) + ">");
4}
5
6[LuaCallCSharp]
7public static class DerivedClassExtensions
8{
9 public static int GetSomeData(this DerivedClass obj)
10 {
11 Debug.Log("GetSomeData ret = " + obj.DMF);
12 return obj.DMF;
13 }
14
15 public static int GetSomeBaseData(this BaseClass obj)
16 {
17 Debug.Log("GetSomeBaseData ret = " + obj.BMF);
18 return obj.BMF;
19 }
20
21 public static void GenericMethodOfString(this DerivedClass obj)
22 {
23 obj.GenericMethod<string>();
24 }
25}
26
27
28print(testobj:GetSomeData())
29print(testobj:GetSomeBaseData()) --访问基类的Extension methods
30testobj:GenericMethodOfString() --通过Extension methods实现访问泛化方法
Lua访问C#的其他注意事项:
Lua调用C#,需要在Xlua中生成"适配代码",则在这个类打入一个[LuaCallCsharp]的标签。
实际开发过程中,lua调用C#用的比较多。
在标有[XLua.LuaCallCsharp]
的C#类中,添加新的方法后,如果是生成了代码类,则必须重新生成或者删除,否则XLua用以前生成的,进行注册查询,会出现Lua异常
Lua语言踩坑
这部分内容是7.27 号补充
1、Lua中的nil和C#中的null不能同等比较!
之前遇到个BUG,偶现报空指针,原来才发现Lua中的nil和C#中的null不能同等比较。Lua中依旧存在引用关系,但是C# 里这个对象已经被销毁了,根据原有的业务逻辑,所以需要两次判空才可以。
基于这种状况有两种解决方式:
第一种就是双重判断,obj==nil or obj:Equals(nil)
1function IsNull( obj )
2 if obj==nil or obj:Equals(nil) then
3 return true;
4 end
5 return false;
6end
第二种就是C#提供判空方法:
1[XLua.LuaCallCSharp]
2public static class MyObj
3{
4 /// <summary>
5 /// 扩展一个Object判空的方法,主要是给lua使用,lua没法用nil和null进行比较
6 /// </summary>
7 /// <param name="obj"></param>
8 /// <returns></returns>
9 public static bool IsNull(this Object obj)
10 {
11 return obj == null;
12 }
13}
2、Lua数组索引从1开始;
3、if not xx
与 if ~ xxx