XLua系列讲解_C#访问Lua中的table类型 

方式1:映射到普通class或struct

这种方式下Xlua会帮你new一个实例,并将对应的数值复制过去。table中的属性可以多于或者少于class的属性。是一种值拷贝的方式(示例工程如下)

1.新建一个 CSharpCallLua.lua.txt 脚本(代码如下)

--[[测试C#访问lua脚本中的 table 类型的全局变量]]

gameLanguage={str1="C#语言",str2="lua语言",str3="C++语言"}	--测试访问 table 类型全局变量

2.新建一个c#脚本,命名为“CSharpCallLuaTableByClass”(代码如下)

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

/// <summary>测试C#调用lua Table类型,方式一:映射到普通class</summary>
public class CSharpCallLuaTableByClass : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    private void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'CSharpCallLua'");

        GameLanguage language = m_LuaEnv.Global.Get<GameLanguage>("gameLanguage");
        print(language.str1);
        print(language.str2);
        print(language.str3);

        //----测试修改映射后的值,是否会对lua中的数据造成影响----
        language.str1 = "我是修改后的参数";
        m_LuaEnv.DoString("print('修改后的 language.str1='..gameLanguage.str1)");
    }


    private void OnDestroy()
    {
        m_LuaEnv.Dispose();
    }


    /// <summary>数据记得和Lua Table中一致</summary>
    public class GameLanguage
    {
        public string str1;
        public string str2;
        public string str3;
    }
}

3. 运行结果如下

这种方式的访问,修改language的值不会影响到lua里面的表的属性

 

方式2:映射到interface[*推荐使用这种方式]

这是一种引用拷贝的方式,由于需要使用“[CSharpCallLua]” 标签,所以需要重新生成Xlua代码(示例工程如下)

 

--------------------[映射到interface方式,访问一个简单的表]--------------------

1.新建一个名为 “CSharpCallLuaTableByInterface” 的C#脚本(代码如下)

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

/// <summary>测试C#调用lua Table类型,方式二:映射到Interface</summary>
public class CSharpCallLuaTableByInterface : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    private void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'CSharpCallLua'");

        IGameLanguage language = m_LuaEnv.Global.Get<IGameLanguage>("gameLanguage");
        print(language.str1);
        print(language.str2);
        print(language.str3);

        //----测试修改映射后的值,是否会对lua中的数据造成影响----
        language.str1 = "我是修改后的参数";
        m_LuaEnv.DoString("print('修改后的 language.str1='..gameLanguage.str1)");
    }


    private void OnDestroy()
    {
        m_LuaEnv.Dispose();
    }


    /// <summary>数据记得和Lua Table中一致</summary>
    [CSharpCallLua]
    public interface IGameLanguage
    {
        string str1 { get; set; }
        string str2 { get; set; }
        string str3 { get; set; }
    }
}

2.因为我们使用 “[CSharpCallLua]” 标签,所以需要重新生成一下Xlua脚本

3. 运行结果如下

这种方式的访问,修改language的值会影响到lua里面的表的属性

 

--------------------[映射到interface方式,访问一个复杂的表]--------------------

1.在 CSharpCallLua.lua.txt 脚本中添加一个复杂的table(修改后的脚本如下)

--[[测试C#访问lua脚本中的 table 类型的全局变量]]


gameLanguage={str1="C#语言",str2="lua语言",str3="C++语言"}	--测试访问 table 类型全局变量

--定义一个综合表(Lua中的OOP思想)
gameUser={

	name="逻辑",
	age=40,
	ID="12384959996",

	Speak=function()
		
		print("调用lua中的Speak函数!")

	end,

	Walking=function ()
		
		print("调用lua中的Walking函数!")

	end,

	Galulation=function (this,num1,num2)
		
		return this.age+num1+num2
		
	end

}

2.新建一个名为 “CSharpCallLuaTableByInterfaceComp” 的C#脚本(代码如下)

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


/// <summary>测试C#调用lua Table类型,方式二:映射到Interface</summary>
public class CSharpCallLuaTableByInterfaceComp : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    private void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'CSharpCallLua'");

        IGameUser gameUser = m_LuaEnv.Global.Get<IGameUser>("gameUser");

        //输出显示
        print(gameUser.ID);
        print(gameUser.name);
        print(gameUser.age);

        //输出调用方法
        gameUser.Speak();
        gameUser.Walking();
        int tmpResult = gameUser.Galulation(100, 200);
        print("Lua中Galulation函数计算结果:"+ tmpResult);

        //----测试修改映射后的值,是否会对lua中的数据造成影响----
        gameUser.name = "我是修改后的参数";
        m_LuaEnv.DoString("print('修改后的 gameUser.name='..gameUser.name)");
    }


    private void OnDestroy()
    {
        m_LuaEnv.Dispose();
    }


    /// <summary>数据记得和Lua Table中一致</summary>
    [CSharpCallLua]
    public interface IGameUser
    {
        string name { get; set; }
        int age { get; set; }
        string ID { get; set; }

        void Speak();
        void Walking();
        int Galulation(int num1, int num2);
    }

}

3.因为我们使用 “[CSharpCallLua]” 标签,所以需要重新生成一下Xlua脚本

4.运行结果如下

 

方式3:通过Dictionary或者List

使用dictionary映射的方式适合映射键值对类型的表

 

--------------------[映射到Dictionary方式,访问一个简单的表]--------------------

1.新建一个名为 “CSharpCallLuaTableByDic” 的C#脚本(代码如下)

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

/// <summary>>测试C#调用lua Table类型,方式三:映射到Dictionary</summary>
public class CSharpCallLuaTableByDic : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    private void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'CSharpCallLua'");

        Dictionary<string, object> dicGameLan = m_LuaEnv.Global.Get<Dictionary<string,object>>("gameLanguage");

        foreach(string key in dicGameLan.Keys)
        {
            print("Key:" + key + "      vualue:" + dicGameLan[key]);
        }


        print("--------测试C#修改值后,对lua是否有影响----------");

        //----测试修改映射后的值,是否会对lua中的数据造成影响----
        dicGameLan["str1"] = "我是修改后的参数";
        m_LuaEnv.DoString("print('修改后的 language.str1='..gameLanguage.str1)");


        print("-----------------我是修改值后-----------------");

        foreach (string key in dicGameLan.Keys)
        {
            print("Key:" + key + "      vualue:" + dicGameLan[key]);
        }

    }

    private void OnDestroy()
    {
        m_LuaEnv.Dispose();
    }

}

2.运行结果如下

这种方式的访问,修改language的值会影响到lua里面的表的属性是“值拷贝”

 

--------------------[映射到List方式,访问一个简单的表]--------------------

使用List映射的方式适合映射数组类型的表

1.在 CSharpCallLua.lua.txt 脚本中添加一个简单的table(修改后的脚本如下)

--[[测试C#访问lua脚本中的 table 类型的全局变量]]


gameLanguage={str1="C#语言",str2="lua语言",str3="C++语言"}	--测试访问 table 类型全局变量

--定义一个综合表(Lua中的OOP思想)
gameUser={

	name="逻辑",
	age=40,
	ID="12384959996",

	Speak=function()
		
		print("调用lua中的Speak函数!")

	end,

	Walking=function ()
		
		print("调用lua中的Walking函数!")

	end,

	Galulation=function (this,num1,num2)
		
		return this.age+num1+num2
		
	end
}

--定义一个简单的表
programLanguage={"C#语言","lua语言","C++语言"}

2.新建一个名为 “CSharpCallLuaTableByList” 的C#脚本(代码如下)

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

/// <summary>>测试C#调用lua Table类型,方式三:映射到List</summary>
public class CSharpCallLuaTableByList : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    private void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'CSharpCallLua'");

        List<string> dicGameLan = m_LuaEnv.Global.Get<List<string>>("programLanguage");

        foreach (string vualue in dicGameLan)
        {
            print("vualue:" + vualue);
        }


        print("--------测试C#修改值后,对lua是否有影响----------");

        //----测试修改映射后的值,是否会对lua中的数据造成影响----
        dicGameLan[0] = "我是修改后的参数";
        m_LuaEnv.DoString("print('修改后的 programLanguage='..programLanguage[1])");


        print("-----------------我是修改值后-----------------");

        foreach (string vualue in dicGameLan)
        {
            print("vualue:" + vualue);
        }

    }

    private void OnDestroy()
    {
        m_LuaEnv.Dispose();
    }
}

2.运行结果如下

这种方式的访问,修改programLanguage的值会影响到lua里面的表的属性是“值拷贝”

 

方式4:通过LuaTable[*不推荐使用]

这种方式的优点是不需要生成代码,确定是比较慢(效率低下),比interface方式要慢一个数量级。所以这种方式不推荐常用,适合用在一些比较复杂且使用频率很低的情况

1.新建一个名为 “CSharpCallLuaTableByLuaTable” 的C#脚本(代码如下)

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

/// <summary>测试C#调用lua Table类型,方式四:映射到LuaTable</summary>
public class CSharpCallLuaTableByLuaTable : MonoBehaviour
{
    private LuaEnv m_LuaEnv;

    private void Start()
    {
        m_LuaEnv = new LuaEnv();
        m_LuaEnv.DoString("require 'CSharpCallLua'");

        XLua.LuaTable tabGameUser = m_LuaEnv.Global.Get<XLua.LuaTable>("gameUser");

        //输出显示
        print("ID:"+tabGameUser.Get<string>("ID"));
        print("name:" + tabGameUser.Get<string>("name"));
        print("age:" + tabGameUser.Get<string>("age"));

        //输出调用方法
        XLua.LuaFunction speak = tabGameUser.Get<XLua.LuaFunction>("Speak");
        speak.Call();

        XLua.LuaFunction walking = tabGameUser.Get<XLua.LuaFunction>("Walking");
        walking.Call();

        XLua.LuaFunction calulation = tabGameUser.Get<XLua.LuaFunction>("Galulation");
        object[] objArray = calulation.Call(tabGameUser,10, 20);
        print("Lua中Galulation函数计算结果:" + objArray[0]);

        //----测试修改映射后的值,是否会对lua中的数据造成影响----
        tabGameUser.Set ("name", "我是修改后的参数");
        m_LuaEnv.DoString("print('修改后的 gameUser.name='..gameUser.name)");
    }


    private void OnDestroy()
    {
        m_LuaEnv.Dispose();
    }

}

2.运行结果如下

这种方式的访问,修改gameUser的值会影响到lua里面的表的属性

 

 

推荐学习资料

XLua入门到精通系列讲解教程目录

Xlua官方插件下载:里面有很多示例工程

lua基础教程:菜鸟教程网

欢迎对Unity技术感兴趣的朋友,加入QQ群:299412191 讨论 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DaLiangChen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值