xLua的基础调用
首先在https://gitee.com/OcxnO/XLua该网站下载xLua,然后解压好后将Assets路径下的文件都复制到我们自己的工程目录Assets下
然后就是如何使用:
这是C#执行Lua语句
//Lua是解释型语言,所以需要获得Lua的解析器
//xLua解析器获得
LuaEnv env = new LuaEnv();
//解析器运行Lua代码,把字符串当成lua代码执行
env.DoString("print('hello world!')");
//解析器释放
env.Dispose();
这是Lua调用C#
LuaEnv env = new LuaEnv();
//Lua调用C#代码(CS.命名空间.类名.方法名(参数))
env.DoString("CS.UnityEngine.Debug.Log('from lua')");
env.Dispose();
Lua可以返回值给C#
LuaEnv env = new LuaEnv();
object[] result = env.DoString("return 100, true");
Debug.Log(result[0]);
Debug.Log(result[1]);
env.Dispose();
然后C#可以让一个Lua脚本运行:DoString里填写require(‘Lua脚本名’)
LuaEnv env = new LuaEnv();
//对应Test.lua
//内置的加载器会扫描预制的目录,查找是否存在Test.lua,预制目录为StreamingAssets
//但是为实现热跟新,一般需要把lua脚本放在可修改的一个目录下
env.DoString("require('Test');");
env.Dispose();
实现一个自定义加载器,从我们设置的路径加载Lua脚本文件
//自定义加载器
//自定义加载器会先于系统内置加载器执行,当自定义加载器加载到文件后,后续的加载器不会继续执行
//当Lua代码执行require()函数时,自定义加载器会尝试获得文件的内容
//参数为lua脚本的路径
//如果需要加载的文件不存在,需要返回null
public byte[] ProjectLoader(ref string filepath)
{
//filepath来自于Lua的require(“文件名”)
//构造路径,才能将require加载的文件指向到我们想放Lua的路径下
//路径可以任意定制(可以把Lua代码放在AB包内)
string path = Application.dataPath;
//Debug.Log(path);
path = path.Substring(0, path.Length - 7) + "/DataPath/Lua/" + filepath + ".lua";
//Debug.Log(path);
if(File.Exists(path))
//将Lua文件读成字节数组
//xLua的解析环境,会执行我们自定义加载器返回的Lua代码
return File.ReadAllBytes(path);
return null;
}
定义好自己的加载器后,要讲加载器添加到xLua 的解析环境中,此时记载Lua文件时优先使用自定义加载器进行加载,若加载到了则默认加载器不执行,否则使用摸人家在其继续加载
LuaEnv env = new LuaEnv();
//将自定义的加载器加入到xLua 的解析环境中
env.AddLoader(ProjectLoader);
env.DoString("require('Test1')");
env.Dispose();
然后我们可以自己封装一个单例xLuaEnv,避免解析器的重复多次创建
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
/// <summary>
/// 自己封装的单例
/// </summary>
public class xLuaEnv
{
private static xLuaEnv _instance;
private LuaEnv _env;
private xLuaEnv()
{
_env = new LuaEnv();
_env.AddLoader(_ProjectLoader);
}
//单例
public static xLuaEnv Instance
{
get
{
if (_instance == null)
_instance = new xLuaEnv();
return _instance;
}
}
//释放解析器
public void DisposeEnv()
{
_env.Dispose();
_instance = null;
}
//DoString方法
public object[] DoString(string code)
{
return _env.DoString(code);
}
/// <summary>
/// 返回env中存储的全局变量
/// Global中存储了Lua中所有定义的全局变量
/// </summary>
public LuaTable Global
{
get
{
return _env.Global;
}
}
//自定义加载器
//自定义加载器会先于系统内置加载器执行,当自定义加载器加载到文件后,后续的加载器不会继续执行
//当Lua代码执行require()函数时,自定义加载器会尝试获得文件的内容
//参数为lua脚本的路径
//如果需要加载的文件不存在,需要返回null
private byte[] _ProjectLoader(ref string filepath)
{
//filepath来自于Lua的require(“文件名”)
//构造路径,才能将require加载的文件指向到我们想放Lua的路径下
//路径可以任意定制(可以把Lua代码放在AB包内)
string path = Application.dataPath;
//Debug.Log(path);
path = path.Substring(0, path.Length - 7) + "/DataPath/Lua/" + filepath + ".lua";
//Debug.Log(path);
if (File.Exists(path))
//将Lua文件读成字节数组
//xLua的解析环境,会执行我们自定义加载器返回的Lua代码
return File.ReadAllBytes(path);
return null;
}
}
Lua调用C#相关学习
Lua调用C#的静态类
首先在C#中写一个静态类,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#静态类以及类的成员变量和方法
/// </summary>
public class LuaCallCStatic : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallCStatic')");
}
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public static class TestStatic
{
public static int id = 99;
public static string name
{
get;
set;
}
public static string Output()
{
return "C2L";
}
public static void Defult(string str = "abc")
{
Debug.Log(str);
}
}
}
然后在Lua调用这个静态类相关数据
--Lua调用C#学习
--1.Lua调用C#静态类
--规则“CS.命名空间.类名.成员变量”
print(CS.C2L.TestStatic.id);
--给静态属性赋值
CS.C2L.TestStatic.name = "admin";
print(CS.C2L.TestStatic.name);
--静态成员方法调用
--规则“CS.命名空间.类名.方法名()”
print(CS.C2L.TestStatic.Output());
CS.C2L.TestStatic.Defult();
CS.C2L.TestStatic.Defult("TestStatic");
Lua实例化C#的类对象
首先在C#中给一个类,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#对象
/// </summary>
public class LuaCallObject : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallObject')");
}
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
public class Npc
{
public string Name;
public int HP
{
get;
set;
}
public Npc()
{
}
public Npc(string name)
{
this.Name = name;
}
public string Output()
{
return Name;
}
}
然后在Lua中实例化这个类对象并使用其数据
--Lua调用C#学习
--2.Lua实例化C#的一个类
--在C#里 Npc obj = new Npc()
--在Lua里的方法: CS.命名空间.对象的构造方法,若没有命名空间可省略
local obj = CS.Npc();
obj.HP = 100;
print(obj.HP);
local obj1 = CS.Npc("admin");
print(obj1.Name);
--表方法希望调用表成员变量(表:函数())
--因为Output返回了对象内的Name,return this.Name 相当于使用了Lua里的self
local name = obj1:Output();
print(name);
--Lua实例化GameObject
--C#实例化GameObject GameObject obj = new GameObject(“name”);
local obj = CS.UnityEngine.GameObject("LuaCreatGO");
print(obj.name);
--使用实例化的C#对象的方法都使用":"
obj:AddComponent(typeof(CS.UnityEngine.BoxCollider));
local engine = CS.UnityEngine;
engine.GameObject("Test");
Lua调用C#的结构体
首先在C#中给一个结构体,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#结构体
/// </summary>
public class LuaCallStruct : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallStruct')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public struct TestStruct
{
public string Name;
public string Output()
{
return Name;
}
}
}
然后在Lua中实例化这个结构体对象并使用其数据
--Lua调用C#学习
--3.Lua调用C#的结构体
--和对象调用保持一致
local obj = CS.C2L.TestStruct();
obj.Name = "admin";
print(obj.Name);
--这里调用结构体对象的方法也是使用":"
local name = obj:Output();
print(name);
Lua调用C#的枚举
首先在C#中给一个枚举,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#枚举
/// </summary>
public class LuaCallEnum : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallEnum')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public enum TestEnum
{
LOL = 1,
Dota2
}
}
然后在Lua中使用这个枚举数据
--Lua调用C#学习
--4.Lua调用C#的枚举
--规则CS.命名空间.枚举名.枚举值
--枚举获得的是userdata自定义数据类型,获得其他语言数据类型时,就是userdata
local enum = CS.C2L.TestEnum.LOL;
print(enum);
print(type(CS.C2L.TestEnum.Dota2));
--转换获得枚举值
print(CS.C2L.TestEnum.__CastFrom(1));
print(CS.C2L.TestEnum.__CastFrom("Dota2"));
Lua调用C#的函数重载
首先在C#中给出几个重载的函数,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#重载函数
/// </summary>
public class LuaCallOverLoad : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallOverLoad')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public class TestOverload
{
public static void Test(int id)
{
Debug.Log("数字类型:" + id);
}
public static void Test(string name)
{
Debug.Log("字符串类型:" + name);
}
public static void Test(int id, string name)
{
Debug.Log("两个数值:" + id + "," + name);
}
}
}
然后在Lua中调用这些重载函数
--Lua调用C#学习
--5.Lua调用C#函数重载
local overload = CS.C2L.TestOverload;
overload.Test(10);
overload.Test("admin");
overload.Test(50, "mlg");
Lua调用C#中继承相关知识
首先在C#中给出一个父类与子类,分别实现其一些数据与方法,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#继承
/// </summary>
public class LuaCallBase : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallBase')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public class Father
{
public string Name = "father";
public void Talk()
{
Debug.Log("这是父类的方法");
}
public virtual void Overide()
{
Debug.Log("这是父类的虚方法");
}
}
public class Child : Father
{
public override void Overide()
{
Debug.Log("这是子类重写的方法");
}
}
}
然后在Lua中实例化父类与子类对象并使用其数据(本质上和Lua实话C#类是一致的)
--Lua调用C#学习
--6.Lua调用C#继承相关
local father = CS.C2L.Father();
print(father.Name);
father:Overide(); --父类的虚方法
father:Talk();
local child = CS.C2L.Child();
print(child.Name);
child:Overide(); --子类重写的方法
child:Talk();
Lua调用C#中类的拓展相关
首先在C#中给出类及其拓展方法,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
/// <summary>
/// Lua调用C#类扩展的方法
/// </summary>
public class LuaCallExtend : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallExtend')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public class TestExtend
{
public void Output()
{
Debug.Log("类本身带的方法");
}
}
//类扩展,需要给扩展方法编写的静态类添加[LuaCallCSharp]这个特性,否则Lua无法调用到
[LuaCallCSharp]
public static class MyExtend
{
public static void Show(this TestExtend obj)
{
Debug.Log("类扩展的方法");
}
}
}
然后在Lua中实例化这个类并调用其拓展方法
--Lua调用C#学习
--7.Lua调用C#类扩展的方法相关
--注意: 类扩展,需要给扩展方法编写的静态类添加[LuaCallCSharp]这个特性,
--否则Lua无法调用到,此特性是在C#脚本中添加的
local extend = CS.C2L.TestExtend();
extend:Output();
extend:Show();
Lua调用C#中的委托,并给委托赋值
首先在C#中给出一个委托,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#的委托,给委托赋值
/// </summary>
public class LuaCallDelegate : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallDelegate')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public delegate void DelegateLua();
public class TestDelegate
{
public static DelegateLua Static;
public DelegateLua Dynamic;
public static void StaticFunc()
{
Debug.Log("C#静态成员函数");
}
}
}
然后在Lua中给这个委托进行赋值,并调用这个委托
--Lua调用C#学习
--8.Lua调用C#委托,给委托赋值
--local delegate = CS.C2L.TestDelegate.Static; --使用这种方式会有点问题,在进行+或-操作时
CS.C2L.TestDelegate.Static = CS.C2L.TestDelegate.StaticFunc; --给委托赋值
--lua中如果添加量函数到静态委托变量后,
--在委托不再使用后,记得释放添加的委托
--delegate = nil;
local func = function()
print("这是Lua的函数");
end
--直接CS.C2L.TestDelegate.Static = func会覆盖原CS.C2L.TestDelegate.StaticFunc
--CS.C2L.TestDelegate.Static = func;
--进行+或-操作时一定要确定已经添加过回调函数
CS.C2L.TestDelegate.Static = CS.C2L.TestDelegate.Static + func;
--CS.C2L.TestDelegate.Static = CS.C2L.TestDelegate.Static - func;
--调用前应确定委托有值
if(CS.C2L.TestDelegate.Static ~= nil) then
CS.C2L.TestDelegate.Static();
end
CS.C2L.TestDelegate.Static = nil;
--根据委托判定赋值方法
--if(CS.C2L.TestDelegate.Static == nil)
--then
-- CS.C2L.TestDelegate.Static = func;
--else
-- CS.C2L.TestDelegate.Static = CS.C2L.TestDelegate.Static + func;
--end
local obj = CS.C2L.TestDelegate();
--注意使用对象的委托使用"."
obj.Dynamic = func;
obj.Dynamic();
obj.Dynamic = nil;
Lua调用C#中的事件,并给事件添加方法
首先在C#中给出一个事件,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#的事件
/// </summary>
public class LuaCallEvent : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallEvent')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public delegate void DelegateTest();
public class TestEvent
{
public static event DelegateTest Static;
public event DelegateTest Dynamic;
public static void StaticFunc()
{
Debug.Log("这是静态函数");
}
public static void CallStatic()
{
if (Static != null)
Static();
}
public void CallDynamic()
{
if (Dynamic != null)
Dynamic();
}
}
}
然后在Lua中给这个事件进行赋值,并调用这个事件
--Lua调用C#学习
--9.Lua添加C#的事件
--C#中的实现:TestEvent.Static += TestEvent.StaticFunc
--Lua添加事件(给静态的添加事件)
CS.C2L.TestEvent.Static("+", CS.C2L.TestEvent.StaticFunc)
CS.C2L.TestEvent.CallStatic();
CS.C2L.TestEvent.Static("-", CS.C2L.TestEvent.StaticFunc)
--动态添加成员变量
local func = function()
print("这是Lua的回调函数");
end
local obj = CS.C2L.TestEvent();
--注意使用对象的事件使用":"
obj:Dynamic("+", func);
obj:CallDynamic()
obj:Dynamic("-", func);
Lua对C#中的泛型的使用
首先在C#中给出一个泛型方法,然后将会用的类型分别实现并调用这个泛型方法,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua调用C#的泛型
/// </summary>
public class LuaCallGenericType : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallGenericType')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public class TestGenericType
{
public void Output<T>(T data)
{
Debug.Log("泛型方法:" + data.ToString());
}
public void Output(float data)
{
Output<float>(data);
}
public void Output(string data)
{
Output<string>(data);
}
}
}
然后在Lua中调用这个方法,也可以通过typeof调用C#中的方法
--Lua调用C#学习
--10.Lua对C#泛型的使用
local obj = CS.C2L.TestGenericType();
obj:Output(99);
obj:Output("admin");
local go = CS.UnityEngine.GameObject("LuaCreate");
--xLua实现了typeof关键字,所以可以使用类型API替代unity内置的泛型方法
go:AddComponent(typeof(CS.UnityEngine.BoxCollider))
Lua对C#中的out,ref的使用
首先在C#中给出一些带有out,ref参数的方法,然后在生命周期函数中使用封装好的单例加载Lua文件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Lua对C#的out和ref的使用
/// </summary>
public class LuaCallOutRef : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("require('C#2Lua/LuaCallOutRef')");
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
namespace C2L
{
public class TestOutRef
{
public static string Func1()
{
return "Func1";
}
public static string Func2(string str1, out string str2)
{
str2 = "Func2 out";
return "Func2";
}
public static string Func3(string str1, ref string str2)
{
str2 = "Func3 Ref";
return "Func3";
}
public static string Func4(ref string str1, string str2)
{
str1 = "Func4 Ref";
return "Func4";
}
}
}
然后在Lua中调用这些方法
--Lua调用C#学习
--11.Lua对C#out和ref的使用
local func1 = CS.C2L.TestOutRef.Func1();
print(func1);
--注意C# out返回的变量会赋值给Lua的第二个接收返回值的变量
--此时out为nil,func2为函数返回值Func2,out1为函数out出的值Func2 out
local out;
local func2, out1 = CS.C2L.TestOutRef.Func2("admin", out);
print(func2, out1,out);
--注意C# ref返回的变量会赋值给Lua的第二个接收返回值的变量,与out一致
--此时ref2为nil,func3为函数返回值Func3,ref1为函数ref出的值Func3 Ref
local ref2;
local func3, ref1 = CS.C2L.TestOutRef.Func3("root", ref2);
print(func3, ref1,ref2);
--即使out,ref作为第一个参数,其结果依然会以Lua 的多返回值进行返回
--结果与上面一致
local ref4;
local func4, ref3 = CS.C2L.TestOutRef.Func4(ref4, "test");
print(func4, ref3, ref4);
C#获取Lua中的全局变量
首先在Lua脚本中定义一些全局变量
--定义全局变量时,隐性的做了{num=100,rate=99.99,isWoman=false,name="admin"}
--这个表是全局的
num = 100;
rate = 99.99;
isWoman = false;
name = "admin";
然后在C#中获取这些全局变量并使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
/// <summary>
/// C#获取Lua的全局变量
/// </summary>
public class CSharpCallVariable : MonoBehaviour
{
void Start()
{
//Lua中代码为return 100
//调用require('Lua2C#/CSharpCallVariable'),是让Lua中返回100,要想接收到返回值,此代码前还要加一个return,即return require('Lua2C#/CSharpCallVariable')
//object[] value = xLuaEnv.Instance.DoString("return require('Lua2C#/CSharpCallVariable')");
//Debug.Log(value[0]);
//LuaEnv中提供了一个成员变量Global,它用于C#获取Lua的全局变量
//Global的数据类型时C#实现的LuaTable,LuaTable时xLua实现C#和Lua中表对应的数据结构
//xLua会将Lua中的全局变量以Table的方式全部存储在Global中
xLuaEnv.Instance.DoString("require('Lua2C#/CSharpCallVariable')");
//通过运行环境,到处全局变量,类型为LuaTable
//LuaTable是C#的数据对象,用于和Lua中的全局变量存储的Table对应
LuaTable g = xLuaEnv.Instance.Global;
//从Lua中,将全局变量提取出来
//参数:Lua中全局变量的名称
//类型:Lua中全局变量的名称所对应的类型
//返回值:变量的值
Debug.Log(g.Get<int>("num"));
Debug.Log(g.Get<float>("rate"));
Debug.Log(g.Get<bool>("isWoman"));
Debug.Log(g.Get<string>("name"));
}
// Update is called once per frame
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
C#获取Lua中的方法
首先在Lua脚本中定义一些方法
func1 = function()
print("这是Lua中的func1");
end
func2 = function(name)
print("这是Lua中的func2,参数是:"..name);
end
func3 = function()
return "这是Lua中的func3";
end
func4 = function()
return "这是Lua中的func4", 100;
end
然后在C#中调用这些方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public delegate void Func1();
public delegate void Func2(string name);
public delegate string Func3();
[CSharpCallLua]//映射产生时,xLua提示添加的
public delegate void Func4(out string name, out int id);
//C#调用Lua的函数方法
public class CSharpCallFunction : MonoBehaviour
{
void Start()
{
xLuaEnv.Instance.DoString("return require('Lua2C#/CSharpCallFunction')");
LuaTable g = xLuaEnv.Instance.Global;
//Lua的函数,会导出为C#的委托类型
Func1 func1 = g.Get<Func1>("func1");
func1();
//向Lua函数传递数据
Func2 func2 = g.Get<Func2>("func2");
func2("admin");
//接收Lua函数的返回值
Func3 func3 = g.Get<Func3>("func3");
Debug.Log(func3() + ",被C#打印");
//Lua多返回值
Func4 func4 = g.Get<Func4>("func4");
string name;
int id;
func4(out name, out id);
Debug.Log(name + "," + id);
}
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
C#获取Lua中的表
首先在Lua脚本中定义一个表及其数据方法
Core = {}
Core.ID = 100;
Core.Name = "root";
Core.IsWoman = false;
Core.Func1 = function(name)
print("这是Core表的Func1函数,接收到C#数据为:"..name);
end
Core.Func2 = function()
return "这是Core表的Func2函数";
end
Core.Func3 = function(self)
print("这是Core表的Func3函数,Core表的成员变量Name是:"..self.Name);
end
function Core:Func4()
print("这是Core表的Func4函数,Core表的成员变量Name是:"..self.Name);
end
然后在C#获取这个表数据并使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public delegate void OneStringParams(string name);
public delegate void TransSelf(LuaTable table);
public delegate string OneStringReturn();
[CSharpCallLua]
public delegate void TransMy(LuaCore table);
//实现了Lua的Table导出到C#的结构体,可以实现C#运行时无GC
[GCOptimize]
public struct LuaCore
{
public int ID;
public string Name;
public bool IsWoman;
public OneStringParams Func1;
public OneStringReturn Func2;
public TransMy Func3;
public TransMy Func4;
}
public class CSharpCallTable : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
xLuaEnv.Instance.DoString("require('Lua2C#/CSharpCallTable')");
//UseLuaTable();
UseStruct();
}
//直接拿到Lua中table内的各个数据
public void UseLuaTable()
{
LuaTable g = xLuaEnv.Instance.Global;
//获得的是全局变量Core,因为它在Lua中是表,所以取出来的是LuaTable类型
LuaTable core = g.Get<LuaTable>("Core");
//获取Name
//参数:table中索引名
//类型:索引对应值得类型
Debug.Log(core.Get<string>("Name"));
core.Set<string, string>("Name", "admin");
OneStringParams osp = core.Get<OneStringParams>("Func1");
osp("admin");
//相当于":"调用
TransSelf ts = core.Get<TransSelf>("Func4");
ts(core);
}
//将Lua中的表导出为C#中的结构体LuaCore,然后就直接使用这个结构体即可
public void UseStruct()
{
LuaTable g = xLuaEnv.Instance.Global;
//将Lua的table导出为LuaCore结构体
LuaCore core = g.Get<LuaCore>("Core");
Debug.Log(core.Name);
core.Func4(core);
}
private void OnDestroy()
{
xLuaEnv.Instance.DisposeEnv();
}
}
xLua的拓展学习可查看网址