方式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官方插件下载:里面有很多示例工程
lua基础教程:菜鸟教程网
欢迎对Unity技术感兴趣的朋友,加入QQ群:299412191 讨论