xLua(五)——C#访问Lua的table

首先在Lua脚本中定义一个table:

一:映射到Class&Struct

在CS脚本中:
——新建映射类中的字段名必须与Lua中table的键名相同(Lua中键为name,那么映射类中字段名也要是name)

using UnityEngine;
using XLua;

public class CallLua: MonoBehaviour
{
    private void Start()
    {
        LuaEnv luaenv = new LuaEnv();

        luaenv.DoString("require 'CsCallLua'");

        Person person = luaenv.Global.Get<Person>("person");
        print(person.age + "-" + person.name);    //输出:15-liu
        person.eat();                             //没有输出

        luaenv.Dispose();
    }

    class Person
    {
        public string name;
        public int age;
        public void eat();
    }
}

二:映射到Interface(推荐使用)
!!!2018版本的Unity无法使用这个方法

在CS脚本中:
——接口中不能包含字段,只能使用属性
——接口需要用[CSharpCallLua]去修饰

——新建的映射接口中的属性名必须与Lua的table键名相同(Lua中键为name,那么映射接口中的属性名也要是name)

using UnityEngine;
using XLua;

public class CallLua: MonoBehaviour
{
    private void Start()
    {
        LuaEnv luaenv = new LuaEnv();

        luaenv.DoString("require 'CsCallLua'");
        IPerson person = luaenv.Global.Get<IPerson>("person");

        print(person.name + "-" + person.age);    //输出:liu-15
        person.eat();                             //输出:LUA:正在吃饭

        luaenv.Dispose();
    }

    [CSharpCallLua]
    interface IPerson
    {
        string name { get; set; }
        int age { get; set; }
        void eat();
    }
}

那么如果Lua中的函数带参数呢?
在Lua脚本中:

在CS中:

运行后发现报错:

报错内容为:尝试将一个数字赋给一个表。这是因为在C#调用Lua的函数时,函数有一个隐藏参数,指向自身。
当我们定义function(a,b)时,其实内部的参数有三个,表名(person),a,b,第一个参数为默认的参数:表名(person),后面的参数才是自己定义的参数,在调用eat(1,2)时相当于我们把数字1赋给了一个表类型person,所以会报错。
有以下两种写法避免这个错误:
1.在Lua中定义函数时增加一个代表自身的参数:

运行后控制台输出:LUA:3

2.在Lua中定义函数时用冒号去定义,这样C#调用Lua时默认带一个self参数。

运行后控制台输出:LUA:3


 映射到Class与映射到Interface的区别:
1.映射到Class不能访问到Lua中的函数,映射到Interface可以访问到Lua中的函数。
2.映射到Class时,xLua内部会帮你new一个实例,然后再将值拷贝赋值给这个实例,如果class比较复杂代价会比较大而且因为是值传递所以修改class的字段值不会同步到table。但是映射到Interface却不是值传递而是引用传递。
可以用luaenv.DoString("print('person.name')")去访问到Lua脚本中的值
     


 三:映射到Dictionary&List

这种方式不需要写太多的代码,因为不需要定义类或者接口,代码比较简洁,但是有很多的局限性。

首先在Lua脚本中写一个table:

1.映射到Dictionary
只能映射table中同时有键和值的数据(类似字典),table中的函数虽然可以映射过来但是结果并不正确。

using UnityEngine;
using System.Collections.Generic;
using XLua;

public class CallLua : MonoBehaviour
{
    private void Start()
    {
        LuaEnv luaenv = new LuaEnv();

        luaenv.DoString("require 'CsCallLua'");
        Dictionary<string, object> personDict = luaenv.Global.Get<Dictionary<string, object>>("person");

        foreach (string key in personDict.Keys)
        {
            print(key + "-" + personDict[key]);                //输出:name-liu
                                                               //输出:age-15
                                                               //输出:eat-functiom():11
        }

        luaenv.Dispose();
    }
}

2.映射到List
只能映射table中没有键的数据(类似数组)。

using UnityEngine;
using System.Collections.Generic;
using XLua;

public class CallLua : MonoBehaviour
{
    private void Start()
    {
        LuaEnv luaenv = new LuaEnv();

        luaenv.DoString("require 'CsCallLua'");
        List<object> personList = luaenv.Global.Get<List<object>>("person");

        foreach (object temp in personList)
        {
            print(temp);                        //输出:1023
                                                //输出:may
        }

        luaenv.Dispose();
    }
}

四:映射到LuaTable

这种方式与映射到字典和列表类似不需要写太多代码,但是性能会慢很多。

using UnityEngine;
using System.Collections.Generic;
using XLua;

public class CallLua : MonoBehaviour
{
    private void Start()
    {
        LuaEnv luaenv = new LuaEnv();

        luaenv.DoString("require 'CsCallLua'");
        LuaTable personTab = luaenv.Global.Get<LuaTable>("person");

        print(personTab.Get<int>("age"));       //输出:15
        print(personTab.Get<string>("name"));   //输出:liu

        luaenv.Dispose();
    }
}

猜你喜欢

转载自blog.csdn.net/LLLLL__/article/details/89321577