首先通过LuaEnv.Dostring()获取到Lua中的内容。然后通过LuaEnv.Global.Get
LuaEnv env=new LuaEnv();
env.DoString("require 'CSharpCallLua' ");//lua文件名
1.获取全局变量的基本属性类型
例:Lua脚本
level=1
name="susu"
isBoy=true
C#脚本
int _level=env.Global.Get("level");
string _name= env.Global.Get("name");
bool _isBoy = env.Global.Get("isBoy");
此处类型必须对应,如果lua中level的值为1.01,而还是通过Get
2.访问一个全局的table
例:Lua脚本
person={
name="susu",
age=100,
Eat=function()
print('hello world我睡觉哦')
end,
Add=function(self, num1,num2)
print(num1+num2)
end
}
function person.Add(self,num1,num2)
print(num1+num2)
end
function person:Compare(num3,num4)
if(num3>num4) then
print(num3)
else
print(num4)
end
end
function person.Return(self,num1,num2)
return 12
end
2.1映射到普通Class或Struct
例:C#脚本
class Person
{
public string name;
public int age;
}
struct MyStruct
{
public string name;
public int age;
}
Person p= env.Global.Get("person");
MyStruct p1 = env.Global.Get("person");
直接复制XLua文档中的原话:
这种方式下xLua会帮你new一个实例,并把对应的字段赋值过去。
table的属性可以多于或者少于class的属性。可以嵌套其它复杂类型。
要注意的是,这个过程是值拷贝,如果class比较复杂代价会比较大。而且修改class的字段值不会同步到table,反过来也不会。
也就是说,这种方式消耗较大,而且你比如生成的p.name="new Name",并不会改变lua中table的属性,同样你改变lua中person中name的值,不能改变p中的值。说白了相当于复制了一份(new),和之前的已经没有任何关系。而且,类的方式似乎无法映射表中的函数。
2.2映射到interface
例:C#脚本
[CSharpCallLua]
public interface IPerson
{
string name { get; set; }
int age { get; set; }
void Eat();
void Add(int a, int b);
void Compare(int a, int b);
int Return(int a, int b);
}
IPerson person= env.Global.Get("person");
person.age = 11;
env.DoString("print(person.age)");
person.Eat();
person.Add(1,2);
person.Compare(4,5);
int num = person.Return(1, 2);
Debug.Log(num);
这种方式依赖于生成代码(如果没生成代码会抛InvalidCastException异常),代码生成器会生成这个interface的实例,如果get一个属性,生成代码会get对应的table字段,如果set属性也会设置对应的字段。甚至可以通过interface的方法访问lua的函数。
和通过class映射不同点在于,接口的使用会直接改变table中的值。并且需要在接口前加上[CSharpCallLua]。而且还可以直接映射函数。
这里一定要注意的一点是Lua脚本中方法参数的问题。C#中person.Add(1,2),可以对应Lua中的三种写法:
写法一:
person={
Add=function(self, num1,num2)
print(num1+num2)
end
}
写法二:
function person.Add(self,num1,num2)
print(num1+num2)
end
写法三:
function person:Add(num1,num2)
print(num1+num2)
end
这里实际上是lua中函数点和冒号的区别
2.3映射到普通Dictionary<>,List<>
这里把上面的Lua脚本稍微改动一下
例:Lua脚本
person={
name="susu",11,234,5,4,3,3,"ssa",false,true,1.02,
age=100,
Eat=function()
print('hello world我睡觉哦')
end
}
例C#脚本:
Dictionary myDictionary =
env.Global.Get>("person");
foreach (var o in myDictionary)
{
Debug.Log(o.Key + " :" + o.Value);
}
List
打印出来的结果,是通过Dictionary方式,可以获取到所有带键值(key)的变量,包括函数。而后面字符串,数值那些不会被映射过来。看Log:
而通过List方式,后面不带Key值的都可以被映射过来,但前面带键值的不会被映射。看Log:
2.4映射到LuaTable
直接使用XLua自带的LuaTable去做映射。不过似乎。。。。不怎么好用。需要挨个儿去获取。看它教程给出的:
这种方式好处是不需要生成代码,但也有一些问题,比如慢,比方式2(Interface)要慢一个数量级,比如没有类型检查。
LuaTable table = env.Global.Get("person");
Debug.Log(table.Get("age"));