XLua学习---C#访问Lua(变量,表,函数)

首先通过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 myList = env.Global.Get>("person");
        for (int i = 0; i < myList.Count; i++)
        {
            Debug.Log(myList[i]);
        }

打印出来的结果,是通过Dictionary方式,可以获取到所有带键值(key)的变量,包括函数。而后面字符串,数值那些不会被映射过来。看Log:

XLua学习---C#访问Lua(变量,表,函数)_第1张图片

而通过List方式,后面不带Key值的都可以被映射过来,但前面带键值的不会被映射。看Log:

XLua学习---C#访问Lua(变量,表,函数)_第2张图片

2.4映射到LuaTable

直接使用XLua自带的LuaTable去做映射。不过似乎。。。。不怎么好用。需要挨个儿去获取。看它教程给出的:

这种方式好处是不需要生成代码,但也有一些问题,比如慢,比方式2(Interface)要慢一个数量级,比如没有类型检查。

    LuaTable table = env.Global.Get("person");
        Debug.Log(table.Get("age"));

 

 

 

你可能感兴趣的:(unity,Xlua)