xlua - c#访问lua table
公共代码
public class Test2 : MonoBehaviour { private LuaEnv m_LuaEnv; void Start() { m_LuaEnv = new LuaEnv(); m_LuaEnv.AddLoader((ref string filePath) => { filePath = filePath.Replace('.', '/'); filePath = $"Assets/{filePath}.lua.txt"; var txtAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(filePath); return Encoding.UTF8.GetBytes(txtAsset.text); }); m_LuaEnv.DoString("require('Lua.Test2')"); //逻辑代码... } void OnDestroy() { if (null != m_LuaEnv) { m_LuaEnv.Dispose(); } } }
1, 将table映射为class或struct
lua脚本:Assets/Lua/Test2.lua.txt
myPerson = { name = "zhangsan", gender = "male" }
类型定义(c#)
public class MyPerson1 { public string name; public int age; private string gender; public string GetGender() { return gender; } } public struct MyPerson2 { public string name; public int age; private string gender; public string GetGender() { return gender; } }
table映射为c#对象
MyPerson1 person1; m_LuaEnv.Global.Get("myPerson", out person1); //映射为class, 只有public属性会被赋值 Debug.Log($"{person1.name}, {person1.age}, {person1.GetGender()}"); MyPerson2 person2; m_LuaEnv.Global.Get("myPerson", out person2); //映射为struct Debug.Log($"{person2.name}, {person2.age}, {person2.GetGender()}");
2, 将table映射为c# interface
注意:需要加上 [CSharpCallLua],然后生成代码,否则会报异常。代码生成的时候,会生成一个接口的实现类(就是lua虚拟机交互代码)
[CSharpCallLua] public interface MyInterface { int Add(int a, int b); //映射lua对象的Add函数 event EventHandler<int> OnAddInvoke; //映射lua对象的add_OnAddInvoke和remove_OnAddInvoke函数 int Num { get; set; } //映射lua对象的Num属性 object this[int index] { get; set; } //映射lua对象的get_Item和set_Item函数 } [CSharpCallLua] public delegate MyInterface MyInterface_New(int num); //委托用于映射lua的new函数
生成的代码类似下面这样
lua脚本:Assets/Lua/Test2.lua.txt
MyInterfaceImpl = {} MyInterfaceImpl.__index = MyInterfaceImpl function MyInterfaceImpl.new(n) local obj = {} setmetatable(obj, MyInterfaceImpl) obj:ctor(n) return obj end function MyInterfaceImpl:ctor(n) self.Num = n or 0 self.m_List = {} self.m_OnAddInvokeListeners = {} end function MyInterfaceImpl:Add(a, b) local result = a + b for i, v_delegate in ipairs(self.m_OnAddInvokeListeners) do v_delegate(self, result) end return result end function MyInterfaceImpl:get_Item(index) return self.m_List[index] end function MyInterfaceImpl:set_Item(index, v) self.m_List[index] = v end function MyInterfaceImpl:add_OnAddInvoke(delegate) table.insert(self.m_OnAddInvokeListeners, delegate) end function MyInterfaceImpl:remove_OnAddInvoke(delegate) for i, v in ipairs(self.m_OnAddInvokeListeners) do if CS.System.Object.Equals(self.m_OnAddInvokeListeners[i], delegate) then table.remove(self.m_OnAddInvokeListeners, i) break end end end
table映射为c#接口
var newDelegate = m_LuaEnv.Global.GetInPath<MyInterface_New>("MyInterfaceImpl.new"); var impl = newDelegate(2); Debug.Log($"Num: {impl.Num}"); impl.OnAddInvoke += OnAddInvokeNotify; Debug.Log($"Add: {impl.Add(1, 2)}"); impl.OnAddInvoke -= OnAddInvokeNotify; Debug.Log($"Add: {impl.Add(5, 6)}"); impl.Num = 5; Debug.Log($"Num: {impl.Num}"); impl[0] = "one"; Debug.Log($"[0]: {impl[0]}");
3, 直接获取LuaTable
不需要生成代码,但性能很慢,且没有类型检查,不建议使用。
var luaTable = m_LuaEnv.Global.Get<LuaTable>("MyInterfaceImpl");var luaFuncNew = luaTable.Get<LuaFunction>("new"); luaFuncNew.Action(new Action<object, int>(OnAddInvokeNotify)); var luaTableImpl = luaFuncNew.Func<int, LuaTable>(2); Debug.Log($"Num: {luaTableImpl.Get<int>("Num")}"); luaTableImpl.Get<LuaFunction>("add_OnAddInvoke").Action(luaTableImpl, new Action<object, int>(OnAddInvokeNotify)); Debug.Log($"Add: {luaTableImpl.Get<LuaFunction>("Add").Call(luaTableImpl, 1, 2)[0]}"); luaTableImpl.Get<LuaFunction>("remove_OnAddInvoke").Action(luaTableImpl, new Action<object, int>(OnAddInvokeNotify)); Debug.Log($"Add: {luaTableImpl.Get<LuaFunction>("Add").Call(luaTableImpl, 5, 6)[0]}"); luaTableImpl.Set("Num", 5); Debug.Log($"Num: {impl.Num}"); luaTableImpl.Get<LuaFunction>("set_Item").Call(luaTableImpl, 0, "one"); Debug.Log($"[0]: {luaTableImpl.Get<LuaFunction>("get_Item").Func<LuaTable, int, string>(luaTableImpl, 0)}");
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2023-02-28 Shader入门精要笔记 - CH10.1_环境映射之折射