编辑
2022-05-02
编程语言
00
请注意,本文编写于 518 天前,最后修改于 113 天前,其中某些信息可能已经过时。

目录

在Lua中new C#对象
Lua访问静态属性、静态方法
Lua中访问C#成员变量和方法
调用C#泛型方法
Lua语言踩坑

XLua是目前国内使用较多的热更新框架(可能是有腾讯加持), Xlua同时也提供了Lua调用C#的能力,其实Lua调用C#的场景更多,要想实现热更新,很多控制逻辑都得写在Lua里,这篇文章主要是记录了Lua如何调用C#,以及踩过的一些坑。

在Lua中new C#对象

例如创建GameObject

lua
print("Lua call C# start...") CS.UnityEngine.GameObject() -- 指定GameObject的名称 CS.UnityEngine.GameObject("NewByLua")

Lua访问静态属性、静态方法

记得最好设置本地Local变量,提高性能

lua
创建对象: local newGo = CS.UnityEngine.GameObject(); local newGo = CS.UnityEngine.GameObject('name') 访问静态属性: CS.UnityEngine.Time.deltaTime CS.UnityEngine.Time.timeScale = 0.5 访问静态方法: CS.UnityEngine.GameObject.Find('name')

小技巧:如果有一些需要经常访问的类,可以用局部变量引用后,通过局部变量进行访问,可以提高性能

lua
local GameObject = CS.UnityEngine.GameObject GameObject.Find('name')

Lua中访问C#成员变量和方法

访问成员属性:. 运算符

lua
local camera = CS.UnityEngine.GameObject.Find("Main Camera") camera.name = "newName";

访问成员方法:. 运算符或 :语法糖

lua
local cameraComponent = camera.GetComponent(camera, "Camera") local cameraComponent = camera:GetComponent("Camera")

注意:在Lua中没有this关键字,所以如果使用 . ,则需要在方法中手动传递对象本身;如果使用:则不需要

带有结构体的参数的方法

在lua端定义一个表去映射结构体:

lua
public struct MyStruct { public string x; public string y; } public void CSharpFunc(MyStruct p) { Debug.Log(p.x); Debug.Log(p.y); } --lua myStructTable={x="C#",y="lua"} obj:CSharpFunc(myStructTable)

调用C#泛型方法

lua中不支持C#的泛型方法,但可以使用扩展方法来调用

lua
public void GenericMethod<T>() { Debug.Log("GenericMethod<" + typeof(T) + ">"); } [LuaCallCSharp] public static class DerivedClassExtensions { public static int GetSomeData(this DerivedClass obj) { Debug.Log("GetSomeData ret = " + obj.DMF); return obj.DMF; } public static int GetSomeBaseData(this BaseClass obj) { Debug.Log("GetSomeBaseData ret = " + obj.BMF); return obj.BMF; } public static void GenericMethodOfString(this DerivedClass obj) { obj.GenericMethod<string>(); } } print(testobj:GetSomeData()) print(testobj:GetSomeBaseData()) --访问基类的Extension methods testobj: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)

lua
function IsNull( obj ) if obj==nil or obj:Equals(nil) then return true; end return false; end

第二种就是C#提供判空方法:

c#
[XLua.LuaCallCSharp] public static class MyObj { /// <summary> /// 扩展一个Object判空的方法,主要是给lua使用,lua没法用nil和null进行比较 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static bool IsNull(this Object obj) { return obj == null; } }

2、Lua数组索引从1开始;

3、if not xxif ~ xxx

lua
C:\Users\15291>lua Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio > a = false > b = true > print((a and b)) false > print((a or b)) true > if not (nil and a) then print("xx") end xx > if not nil and a then print("xx") end > >

本文作者:Tim

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!