这篇文章记录一下C#如何获取Lua中的Table。关于如何获取Lua全局变量和函数的问题,可以看一下我的这篇文章【Unity】热更新之xLua C#获取Lua全局变量 / 函数。
先在lua中定义两个table,一个类型一致,一个类型不一致。
--lua
list1 = { 1, 2, 3, 4, 5 }
list2 = { 7, 8.9, "abc", true }
C#中想要得到这两个table,同样是通过Global.Get来获得。
储存了不同类型元素的table映射到C#中可以用List
//C#
List<int> intList = Global.Get<List<int>>("list1");
for(int i = 0; i < intList.Count; i++)
Debug.Log(intList[i]);
Debug.Log("-----------------------");
List<object> objList = Global.Get<List<object>>("list2");
for (int i = 0; i < objList.Count; i++)
Debug.Log(objList[i]);
lua中定义一个自定义索引的table
--lua
dic1 = {
["a"] = 1,
["b"] = 2,
["c"] = 3,
["d"] = 4
}
C#中应用Dictionary来获取table
//C#
Dictionary<string, int> dic1 = Global.Get<Dictionary<string, int>>("dic1");
foreach(string key in dic1.Keys)
{
Debug.Log(key + " - " + dic1[key]);
}
在Lua中定义一个table模拟C#中的类
--lua
testClass = {
intV = 1,
strV = "abc",
boolV = false,
floatV = 1.32,
func = function()
print("这是lua中的函数")
end,
--表中嵌套表,相当于类中包含一个类
class2 = {
value = 2
}
}
C#中需要定义与Lua table一致的类,成员变量名需要和Lua table中的名字一致,访问权限必须是public。
public class TestClass
{
public int intV;
public string strV;
public bool boolV;
public float floatV;
public UnityAction func;
//这个是类中包含的另一个类
public TestClass2 class2;
}
public class TestClass2
{
public int value;
}
获取方法同样是通过Global.Get获取,完整代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.IO;
using UnityEngine.Events;
public class TestClass
{
public int intV;
public string strV;
public bool boolV;
public float floatV;
public UnityAction func;
public TestClass2 class2;
}
public class TestClass2
{
public int value;
}
public class LuaTest : MonoBehaviour
{
LuaEnv luaEnv = new LuaEnv();
private LuaTable Global => luaEnv.Global;
// Start is called before the first frame update
void Start()
{
//添加自定义加载器
luaEnv.AddLoader(MyCustomLoader);
//luaEnv.AddLoader(MyABCustomLoader);
luaEnv.DoString("require('MyLua01')");
//获得Lua中的Table
TestClass testClass = Global.Get<TestClass>("testClass");
Debug.Log(testClass.intV);
Debug.Log(testClass.strV);
Debug.Log(testClass.boolV);
Debug.Log(testClass.floatV);
testClass.func();
Debug.Log(testClass.class2.value);
}
///
/// 自定义加载器,用来加载自定义路径中的Lua文件
///
/// Lua文件名
/// Lua文件字节数组
byte[] MyCustomLoader(ref string filepath)
{
//根据文件名,自定义加载路径,我这里是Asset文件夹下新建了一个Lua文件夹
string path = Application.dataPath + "/Lua/" + filepath + ".lua";
//这里判断一下文件是否存在 File需要引用System.IO命名空间
if (File.Exists(path))
{
//如果存在,将文件读取出来并返回出去
return File.ReadAllBytes(path);
}
//如果不存在就返回空
return null;
}
}
同样在Lua中定义一个table
--lua
testClass = {
intV = 1,
strV = "abc",
boolV = false,
floatV = 1.32,
func = function()
print("这是lua中的函数")
end
}
与类映射不同的是,接口不能有成员变量,必须用属性代替。所以,定义以下接口来映射table。接口必须添加[CSharpCallLua]特性,然后到unity中,点击XLua - Generate Code生成代码。(备注:如果生成代码后,又修改了接口,需要先点击XLua - Clear Generated Code清除生成的代码,然后再点击XLua - Generate Code生成代码。)
[CSharpCallLua]
public interface I_TestInterface
{
int intV { get; set; }
string strV { get; set; }
bool boolV { get; set; }
float floatV { get; set; }
UnityAction func { get; set; }
}
完整代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System.IO;
using UnityEngine.Events;
[CSharpCallLua]
public interface I_TestInterface
{
int intV { get; set; }
string strV { get; set; }
bool boolV { get; set; }
float floatV { get; set; }
UnityAction func { get; set; }
}
public class LuaTest : MonoBehaviour
{
LuaEnv luaEnv = new LuaEnv();
private LuaTable Global => luaEnv.Global;
// Start is called before the first frame update
void Start()
{
//添加自定义加载器
luaEnv.AddLoader(MyCustomLoader);
//luaEnv.AddLoader(MyABCustomLoader);
luaEnv.DoString("require('MyLua01')");
I_TestInterface test = Global.Get<I_TestInterface>("testClass");
Debug.Log(test.intV);
Debug.Log(test.strV);
Debug.Log(test.boolV);
Debug.Log(test.floatV);
test.func();
//这里注意,接口修改对应的属性的值会直接影响到Lua中table中的值,下次再映射此table,就会发现值已经改了
test.intV = 12345;
I_TestInterface test2 = Global.Get<I_TestInterface>("testClass");
Debug.Log(test2.intV);
}
///
/// 自定义加载器,用来加载自定义路径中的Lua文件
///
/// Lua文件名
/// Lua文件字节数组
byte[] MyCustomLoader(ref string filepath)
{
//根据文件名,自定义加载路径,我这里是Asset文件夹下新建了一个Lua文件夹
string path = Application.dataPath + "/Lua/" + filepath + ".lua";
//这里判断一下文件是否存在 File需要引用System.IO命名空间
if (File.Exists(path))
{
//如果存在,将文件读取出来并返回出去
return File.ReadAllBytes(path);
}
//如果不存在就返回空
return null;
}
}
这里需要注意,接口修改对应的属性的值会直接影响到Lua中table中的值,下次再映射此table,就会发现值已经被修改了。
以上就是这篇文章的所有内容了,此为个人学习记录,如有哪个地方写的有误,劳烦大佬指出,感谢,希望对各位看官有所帮助!