文件加载
使用LuaEnv中的DoString方法来执行Lua脚本。
因为创建一个LuaEnv相当于创建了一个lua虚拟机,所以一个游戏最好只有一个LuaEnv。
1 | // 执行lua代码 |
官方建议的加载Lua脚本方式是:整个程序就一个DoString(“require ‘main’”),然后在main.lua加载其它脚本(类似lua脚本的命令行执行:lua main.lua)。
C#访问Lua普通全局变量
先加载lua脚本,再通过LuaEnv.Global.Get获取变量。
1 | TextAsset ta = Resources.Load<TextAsset>("Lua/variable.lua"); |
C#访问Lua table的四种方法
需要注意的是,在构建C#中对应的结构时,接口一定要是public修饰,否则会报错。类最好也是,但是经测试,没有报错。
映射到普通class或struct
table的属性可以多于或者少于class的属性,也就是不一定都需要做映射。这个过程是值拷贝,如果class比较复杂代价会比较大。而且修改class的字段值不会同步到table,反过来也不会。1
2
3
4
5
6
7public class Person
{
public string name;
public int age;
}
Person p = env.Global.Get<Person>("g_tbl");
映射到接口
一定要加[CSharpCallLua]和public,否则会报错。1
2
3
4
5
6
7g_int = 1
g_str = "Hello World Variable"
g_bool = false
g_tbl = {name = "Juhnny", age = 12}
g_tbl.say = function(this, str)
print(str)
end
1 | [] |
映射到Dictionary和List
这种方法较方法2更为轻量级,但是要求table下key和value类型一致。1
2g_dic = {apple = "iPhone", flower = "Huawei"}
g_list = {1, 3, 5, 7, 9}
1 | Dictionary<string, string> dic = env.Global.Get<Dictionary<string, string>>("g_dic"); |
映射到LuaTable
这种方法比较慢,而且没有类型检查,不推荐使用。1
2
3
4
5
6
7
8LuaTable tab = env.Global.Get<LuaTable>("g_tbl");
string name = tab.Get<string>("name");
int age = tab.Get<int>("age");
print(string.Format("Name is {0}, age is {1}", name, age));
foreach (string key in tab.GetKeys())
{
print(tab.Get<object>(key));
}
C#访问Lua全局函数
使用delegate映射
这种是建议的方式,性能好很多,而且类型安全,但是要生成代码。支持带返回值,多返回值,甚至返回值都可以是delegate。1
2
3
4
5
6
7
8g_func1 = function()
print("FF")
end
g_func2 = function(num)
print(num)
return num, "Yoshida", "SE"
end
1 | [] |
在过去的一些版本中,需要在不使用后,将接收到的函数销毁,否则会在LuaEnv.Dispose的时候报错。
使用LuaFunction
与上一种方法优缺点相反,不推荐使用。1
2LuaFunction func = env.Global.Get<LuaFunction>("g_func2");
object[] res = func.Call(14);
Lua调用C
1 | // 读静态属性 |
其它注意事项
方法的参数处理
Lua调用侧的参数处理规则:C#的普通参数算一个输入形参,ref修饰的算一个输入形参,out不算,然后从左往右对应lua 调用侧的实参列表。
Lua调用侧的返回值处理规则:C#函数的返回值(如果有的话)算一个返回值,out算一个返回值,ref算一个返回值,然后从左往右对应lua的多返回值。
可变参数的处理1
2
3
4
5// 对于C#的如下方法:
void VariableParamsFunc(int a, params string[] strs)
// 可以在lua里头这样调用:
testobj:VariableParamsFunc(5, 'hello', 'john')
枚举1
2
3
4
5
6
7
8
9
10// 枚举值就像枚举类型下的静态属性一样。
testobj:EnumTestFunc(CS.Tutorial.TestEnum.E1)
上面的EnumTestFunc函数参数是Tutorial.TestEnum类型的。
枚举类支持__CastFrom方法,可以实现从一个整数或者字符串到枚举值的转换,例如:
CS.Tutorial.TestEnum.__CastFrom(1)
CS.Tutorial.TestEnum.__CastFrom('E1')
委托
1 | -- 使用+-号来实现委托 |