C#调用Lua

目录

xLua导入

打包工具导入

单例基类导入与AB包管理器导入

Lua解析器

文件加载与重定向

Lua解析器管理器

全局变量获取

全局函数获取

对于无参数无返回值

对于有参数有返回值

对于多返回值

对于变长参数

完整代码

List与Dictionary映射Table

类映射Table

接口映射Table

LuaTable映射Table

xLua导入

在github上搜索xLua,选择第一个下载,进入master的Assets里面导入

导入后可以在工具栏中看到XLua,这样导入就完成了。

打包工具导入

这里上篇中有讲,可以看一下 https://blog.csdn.net/sara_shengxin/article/details/144596428?spm=1001.2014.3001.5502

单例基类导入与AB包管理器导入

获取链接http://通过网盘分享的文件:Base.rar 链接: https://pan.baidu.com/s/1-WpLVyrRFowVAs1AudrbdQ?pwd=raux 提取码: raux

AB包管理器导入,在上一篇中最终的代码复制过来就可以ABMgr

Lua解析器

构建一个lua解析器,使得能够在unity中执行lua语言,提供的方法主要有:DoString(),Tick(),Dispose().此时调用lua脚本我们要将他放在Resources文件夹里面,且要修改lua脚本的后缀为.txt

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//引入命名空间
using XLua;
public class Lesson1LuaEnv : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        //lua解析器 能够在Unity中执行lua语言
        LuaEnv env= new LuaEnv();

        //执行Lua语言
        env.DoString("print('nihao')");

        //执行一个lua脚本 ,利用lua中的多脚本执行require
        env.DoString("require('Main')");//默认脚本加载路径在resource中并且后缀为.txt

        //帮助清除Lua中我们没有手动清除的对象,垃圾回收
        //帧更新中定时执行 或者切场景的时候执行
        env.Tick();

        //销毁Lua解析器
        env.Dispose();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

在lua的Main脚本中,我们这样写

Lua 复制代码
print("主lua脚本启动")

文件加载与重定向

上面所说的加载lua脚本的方法虽然可行,但是比较麻烦。我们还可以利用XLua中提供的一个重定向的方法AddLoader(),允许我们自定义加载lua的方法

cs 复制代码
using System.IO;
using UnityEngine;
using XLua;

public class Lesson2Loader : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaEnv env = new LuaEnv();
        //xlua提供一个路径重定向的方法
        //允许我们自定义加载lua文件的规则
        //当我们执行lua语言 require时,相当于执行一个lua脚本
        //他会执行我们自定义传入的这个函数
        env.AddLoader(MyCustomLoader);

        env.DoString("require('Main')");
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    //自动执行
    private byte[] MyCustomLoader(ref string filepath)
    {

        //通过函数中的逻辑加载lua文件
        //传入的参数是require执行lua脚本文件名
        //拼接一个lua文件所在的路径
        string path =Application.dataPath+"/LUA/"+filepath+".lua";
        Debug.Log(path);

        //有路径就去加载文件
        //File知识点 C#提供的文件读写的类
        //判断文件是否存在
        if(File.Exists(path))
        {
            return File.ReadAllBytes(path);
        }
        else
        {
            Debug.Log("文件不存在"+filepath);
        }
        
        return null;
    }
}

使用require("lua脚本")的方法会先去自定义的函数里面找文件,如果找到则返回,找不到会在默认路径里面寻找

Lua解析器管理器

有了上面的经验,我们可以创建一个lua管理器,为C#解析lua提供一些通用的方法

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Rendering.VirtualTexturing;
using XLua;
/// <summary>
/// lua管理器
/// 提供lua解析器
/// 保证解析器唯一性
/// 提供通用的方法
/// </summary>
public class LuaMgr:BaseManager<LuaMgr>
{
    //执行lua语言的函数
    //释放垃圾
    //重定向
    //销毁
    private LuaEnv luaenv;
    
    /// <summary>
    /// 得到lua中的_G
    /// </summary>
    public LuaTable Global
    {
        get
        {
            return luaenv.Global;
        }
    }


    /// <summary>
    /// 初始化
    /// </summary>
    public void Init()
    {
        if (luaenv != null)
            return;
        luaenv = new LuaEnv();

        //重定向
        luaenv.AddLoader(MyCustomLoader);
        luaenv.AddLoader(MyCustomLoaderAB);
    }
    //自动执行
    private byte[] MyCustomLoader(ref string filepath)
    {

        //通过函数中的逻辑加载lua文件
        //传入的参数是require执行lua脚本文件名
        //拼接一个lua文件所在的路径
        string path = Application.dataPath + "/LUA/" + filepath + ".lua";

        //有路径就去加载文件
        //File知识点 C#提供的文件读写的类
        //判断文件是否存在
        if (File.Exists(path))
        {
            return File.ReadAllBytes(path);
        }
        else
        {
            Debug.Log("文件不存在" + filepath);
        }

        return null;
    }

    //Lua脚本会放在AB包中
    //最终我们会通过加载AB包再加载其中的Lua脚本资源来执行
    //AB包中如果要加载文本,后缀还是会有限制 .lua不能被识别
    //打包时还是要把lua文件后缀改为txt
    //重定向加载AB中的lua脚本
    private byte[] MyCustomLoaderAB(ref string filepath)
    {
        Debug.Log("进入AB包加载");
        从AB包中加载Lua文件
        加载AB包
        //string path = Application.streamingAssetsPath + "/LUA";
        //AssetBundle ab=AssetBundle.LoadFromFile(path);

        加载Lua文件,返回
        //TextAsset tx = ab.LoadAsset<TextAsset>(filepath + ".lua");

        加载lua文件里的byte数组
        //return tx.bytes;

        //通过AB包管理器加载的lua脚本
        TextAsset lua =ABgr.GetInstance().LoadRes<TextAsset>("LUA", filepath + ".lua");
        if (lua != null)
        {
            return lua.bytes;
        }
        else
        {
            Debug.Log("重定向失败"+filepath);
        }
        return null;


    }

    /// <summary>
    /// 传入lua文件名,执行lua脚本
    /// </summary>
    /// <param name="filename"></param>
    public void DoLuaFile(string filename)
    {
        string s = string.Format("require('{0}')", filename);
        DoString(s);
    }



    /// <summary>
    /// 执行lua语言
    /// </summary>
    /// <param name="s"></param>
    public void DoString(string s)
    {
        if(luaenv == null)
        {
            Debug.Log("解析器未初始化");
            return;
        }
        luaenv.DoString(s);
    }

    /// <summary>
    /// 释放垃圾
    /// </summary>
    public void Tick()
    {
        if (luaenv == null)
        {
            Debug.Log("解析器未初始化");
            return;
        }
        luaenv.Tick();
    }

    /// <summary>
    /// 销毁
    /// </summary>
    public void Dispose()
    {
        if (luaenv == null)
        {
            Debug.Log("解析器未初始化");
            return;
        }
        luaenv.Dispose();
        luaenv= null;
    }

}

全局变量获取

我们修改lua中Main脚本的内容

Lua 复制代码
print("主lua脚本启动")
--Unity中写lua执行
--xlua帮我们处理
--只要是执行lua脚本都会自动进入我们的重定向函数中找文件
require("Test")

然后我们在test脚本中声明一些变量,必须是全局变量,因为通过C#不能获取Lua中的本地变量

Lua 复制代码
testnum=1
testbool=true
testfloat=11.8
teststring="xxxx"

然后我们通过Global属性,利用Get获取,如果我们要修改值的内容,利用Set进行修改。如果直接修改是不能改变lua中的内容的,因为是浅拷贝

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson4CallVarlable : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaMgr.GetInstance().Init();

        LuaMgr.GetInstance().DoLuaFile("Main");

        //使用lua解析器中的luaenv中的Global属性
        //获取
        int i=LuaMgr.GetInstance().Global.Get<int>("testnum");
        Debug.Log(i);
        //该值
        LuaMgr.GetInstance().Global.Set("testnum",100);
        int i2 = LuaMgr.GetInstance().Global.Get<int>("testnum");
        Debug.Log(i2);
        //不能获取lua中的本地局部变量
        //int test=LuaMgr.GetInstance().Global.Get<int>("test");
        //Debug.Log(test);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

全局函数获取

在获取全局函数时,我们有四种类型的函数:无参数无返回值,有参数有返回值,多返回值,变长参数。

对于无参数无返回值

我们有四种方式获取:

cs 复制代码
//声明一个无参数无返回值的委托
public delegate void CallNoReturn();

//start中调用

CallNoReturn callNoReturn = LuaMgr.GetInstance().Global.Get<CallNoReturn>("testFun");
callNoReturn();

//Unity自带的委托(无返回值)
UnityAction ua= LuaMgr.GetInstance().Global.Get<UnityAction>("testFun");
ua();

 //C#的委托(无返回值)
Action action = LuaMgr.GetInstance().Global.Get<Action>("testFun");
action();

 //xLua 提供的一种获取函数的方式(尽量少用,会产生一些垃圾)
LuaFunction lf= LuaMgr.GetInstance().Global.Get<LuaFunction>("testFun");
lf.Call();
Lua 复制代码
--无参无返回
testFun=function (  )
	print("无参数无返回")
end

对于有参数有返回值

也是类似的:其中要注意的时,由于必须添加[CSharpCallLua],因此要在Xlua中先清除生成代码,再生成代码,然后再运行

cs 复制代码
/声明一个有参数有返回值的委托
//该特性是在xlua命名空间中的
[CSharpCallLua]
public delegate int CallHaveReturn(int a);


//start中调用
CallHaveReturn callHaveReturn = LuaMgr.GetInstance().Global.Get<CallHaveReturn>("testFunc");
Debug.Log("有参有返回"+callHaveReturn(8));

Func<int,int> func = LuaMgr.GetInstance().Global.Get<Func<int, int>>("testFunc");
Debug.Log(func(5));

LuaFunction lf1 = LuaMgr.GetInstance().Global.Get<LuaFunction>("testFunc");
Debug.Log(lf1.Call(19)[0]);//一个返回值返回数组第0个
Lua 复制代码
--有参有返回
testFunc=function ( a)
	print("有参数有返回值")
	return a+4
	
end

对于多返回值

我们使用out或者ref来接收,他们两个类似,区别为使用out不需要初始化,使用ref需要为他初始化

同样保存后也需要在XLua中重新生成代码再运行

我们还可以使用LuaFunction,使用数组来存他的多个返回值然后再遍历输出

cs 复制代码
//声明一个多返回值的委托 用out
[CSharpCallLua]
public delegate int CallMutReturn(int a, out int b, out bool c, out float d);

//声明一个多返回值的委托 用ref
[CSharpCallLua]
public delegate int CallMutReturn1(int a, ref int b, ref bool c, ref float d);


 CallMutReturn callMutReturn = LuaMgr.GetInstance().Global.Get<CallMutReturn>("testFunc3");
int b;
bool c;
float d;
Debug.Log("第一个返回值" + callMutReturn(123,out b,out c,out d));
Debug.Log(b+"_"+c+"_"+d);

CallMutReturn1 callMutReturn1 = LuaMgr.GetInstance().Global.Get<CallMutReturn1>("testFunc3");
int b1=0;
bool c1=false;
float d1=0.0f;
Debug.Log("第一个返回值" + callMutReturn1(100, ref b1, ref c1, ref d1));
Debug.Log(b1 + "_" + c1 + "_" + d1);

//使用luaFunction
LuaFunction lf2 = LuaMgr.GetInstance().Global.Get<LuaFunction>("testFunc3");
object[] obj = lf2.Call(10);
for(int i = 0; i < obj.Length; i++)
   {
        Debug.Log("第"+i+"个返回值是"+obj[i]);
   }

对于变长参数

我们使用自定义的一个委托,变长参数我们使用params,如果能确定是同一类型,后面可以使用该类型,如果有各种类型就使用object

cs 复制代码
//声明一个变长参数的委托
[CSharpCallLua]
public delegate void CallChange(int a,params object[] obj);

CallChange callChange = LuaMgr.GetInstance().Global.Get<CallChange>("testFunc4");
callChange(3,false,"jwhdkh",7.666,658);

LuaFunction lf3 = LuaMgr.GetInstance().Global.Get<LuaFunction>("testFunc4");
lf3.Call(2, false, "jwhdkh", 7.666, 658);
Lua 复制代码
--变长参数
testFunc4=function ( a,... )
	print("变长参数")
	print(a)
	arg={...}
	for k,v in pairs(arg) do
		print(k,v)
	end
end

完整代码

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using XLua;

//声明一个无参数无返回值的委托
public delegate void CallNoReturn();

//声明一个有参数有返回值的委托
//该特性是在xlua命名空间中的
[CSharpCallLua]
public delegate int CallHaveReturn(int a);

//声明一个多返回值的委托 用out
[CSharpCallLua]
public delegate int CallMutReturn(int a, out int b, out bool c, out float d);

//声明一个多返回值的委托 用ref
[CSharpCallLua]
public delegate int CallMutReturn1(int a, ref int b, ref bool c, ref float d);

//声明一个变长参数的委托
[CSharpCallLua]
public delegate void CallChange(int a,params object[] obj);//如果lua中后面的变长数组全是int或者是一种类型,那么可以就写params int[] b或者params string[] c
public class Lesson5CallFunction : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().DoLuaFile("Main");

        无参无返回的获取
        //委托
        CallNoReturn callNoReturn = LuaMgr.GetInstance().Global.Get<CallNoReturn>("testFun");
        callNoReturn();
        //Unity自带的委托(无返回值)
        UnityAction ua= LuaMgr.GetInstance().Global.Get<UnityAction>("testFun");
        ua();

        //C#的委托(无返回值)
        Action action = LuaMgr.GetInstance().Global.Get<Action>("testFun");
        action();

        //xLua 提供的一种获取函数的方式(尽量少用,会产生一些垃圾)
        LuaFunction lf= LuaMgr.GetInstance().Global.Get<LuaFunction>("testFun");
        lf.Call();



        //有参有返回
        CallHaveReturn callHaveReturn = LuaMgr.GetInstance().Global.Get<CallHaveReturn>("testFunc");
        Debug.Log("有参有返回"+callHaveReturn(8));

        Func<int,int> func = LuaMgr.GetInstance().Global.Get<Func<int, int>>("testFunc");
        Debug.Log(func(5));

        LuaFunction lf1 = LuaMgr.GetInstance().Global.Get<LuaFunction>("testFunc");
        Debug.Log(lf1.Call(19)[0]);//一个返回值返回数组第0个



        ///多返回值
        //使用out与ref来接收(out接收外面的值不需要初始化,ref需要初始化)
        CallMutReturn callMutReturn = LuaMgr.GetInstance().Global.Get<CallMutReturn>("testFunc3");
        int b;
        bool c;
        float d;
        Debug.Log("第一个返回值" + callMutReturn(123,out b,out c,out d));
        Debug.Log(b+"_"+c+"_"+d);

        CallMutReturn1 callMutReturn1 = LuaMgr.GetInstance().Global.Get<CallMutReturn1>("testFunc3");
        int b1=0;
        bool c1=false;
        float d1=0.0f;
        Debug.Log("第一个返回值" + callMutReturn1(100, ref b1, ref c1, ref d1));
        Debug.Log(b1 + "_" + c1 + "_" + d1);

        //使用luaFunction
        LuaFunction lf2 = LuaMgr.GetInstance().Global.Get<LuaFunction>("testFunc3");
        object[] obj = lf2.Call(10);
        for(int i = 0; i < obj.Length; i++)
        {
            Debug.Log("第"+i+"个返回值是"+obj[i]);
        }



        变长参数
        CallChange callChange = LuaMgr.GetInstance().Global.Get<CallChange>("testFunc4");
        callChange(3,false,"jwhdkh",7.666,658);

        LuaFunction lf3 = LuaMgr.GetInstance().Global.Get<LuaFunction>("testFunc4");
        lf3.Call(2, false, "jwhdkh", 7.666, 658);
    }

  
}

List与Dictionary映射Table

我们在lua中分别创建一个同类型与不同类型的列表与字典,列表一般用来没有自定义索引的表,如果确定类型就用指定类型,如果不确定就用object。字典一般是用来有自定义索引的表,如果确定类型就用指定类型,如果不确定就用object。

Lua 复制代码
--List
testlist ={1,2,3,4,5,6}
testlist2={"vv",4,34,true,4.68}

--Dictionary
testDic={
	["1"]=1,
	["2"]=2,
	["3"]=3,
	["4"]=4,
	["5"]=5
}
testDic2={
	["1"]=1,
	[true]=2,
	[false]=true,
	["4"]=4.5,
	["5"]=false
}

注意:遍历列表时用for,遍历字典时我们使用的时foreach。并且无论是字典还是列表,都为浅拷贝。

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson6CallListDic : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().DoLuaFile("Main");

        //同一类型 List
        List<int> list = LuaMgr.GetInstance().Global.Get<List<int>>("testlist");
        Debug.Log("*********************List**********************");
        for(int i = 0; i < list.Count; i++)
        {
            Debug.Log(list[i]);
        }
        //为值拷贝 浅拷贝,不会改变lua中的值
        //list[0] = 100;
        //List<int> list2 = LuaMgr.GetInstance().Global.Get<List<int>>("testlist");
        //for (int i = 0; i < list.Count; i++)
        //{
        //    Debug.Log(list2[i]);
        //}
        //不指定类型 List
        List<object> list3= LuaMgr.GetInstance().Global.Get<List<object>>("testlist2");
        for (int i = 0; i < list3.Count; i++)
        {
            Debug.Log(list3[i]);
        }

        Debug.Log("*********************Dic**********************");
        //同一类型 Dic
        Dictionary<string,int> dic1= LuaMgr.GetInstance().Global.Get<Dictionary<string,int>>("testDic");
        foreach(string item in dic1.Keys)
        {
            Debug.Log(item + "_" + dic1[item]);
        }
        //若直接修改值,也为浅拷贝

        //不同类型 Dic
        Dictionary<object, object> dic2 = LuaMgr.GetInstance().Global.Get<Dictionary<object, object>>("testDic2");
        foreach (object item in dic2.Keys)
        {
            Debug.Log(item + "_" + dic2[item]);
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

类映射Table

lua中没有类,用表自定义类

Lua 复制代码
testClass={
	testint=5,
	testbool=true,
	testfloat=4.5,
	teststring="xnbsa",
	testFun=function (  )
		print("243566764")
	end
    testInClass={
		testInInt=66,
		testInString=("*****************这是一个嵌套表******************")
	}
}

在C#中,我们也定义一个类,其中声明的成员变量名字要和lua中一致,数量可以多也可以少。类中的嵌套在C#上的表现也是再声明一个类,其中的成员变量与函数名也要相同。

其中,在类中的拷贝为深拷贝,在C#中修改值会同步修改lua中的值

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class CallLuaClass
{
    //在类中声明成员变量 名字要和lua中的一样
    //数量可以比lua中多也可以更少
    public int testint;
    public float testfloat;
    public bool testbool;
    public string teststring;
    public UnityAction testFun;
    public CallLuaInClass testInClass;
}

public class CallLuaInClass
{
    public int testInInt;
    public string testInString;
}
public class Lesson7CallClass : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().DoLuaFile("Main");

        CallLuaClass obj = LuaMgr.GetInstance().Global.Get<CallLuaClass>("testClass");
        Debug.Log(obj.testint);
        Debug.Log(obj.testfloat);
        Debug.Log(obj.testbool);
        //Debug.Log(obj.teststring);
        //obj.testFun();
        Debug.Log(obj.testInClass.testInInt);
        Debug.Log(obj.testInClass.testInString);
        //浅拷贝
        //obj.testint = 999;
        //CallLuaClass obj1 = LuaMgr.GetInstance().Global.Get<CallLuaClass>("testClass");
        //Debug.Log(obj1.testint);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

接口映射Table

lua中的脚本我们继续使用类的代码

Lua 复制代码
testClass={
	testint=5,
	testbool=true,
	testfloat=4.5,
	teststring="xnbsa",
	testFun=function (  )
		print("243566764")
	end
}

但是在C#中,接口是不允许有成员变量的,我们要使用属性来接收lua中的变量。

由于我们要使用[CSharpCallLua],在每一次对接口进行修改后我们都需要在XLua中进行清空然后生成代码再运行。

接口也可以有嵌套,嵌套方式与类中相似

注意的是接口中的拷贝也为深拷贝

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using XLua;

[CSharpCallLua]
//接口中是不允许有成员变量,因此我们用属性来接收
//与类相似,内容属性可多可少,但是每一次修改interface结构后都需要先清空xLua再生成运行
//嵌套几乎和类一样,无非就是要遵循接口的规则
public interface ICCallLua
{
    int testint
    {
        get; set;
    }
    bool testbool
    {
        get; set;
    }

    float testfloat
    {
        get; set;
    }

    string teststring
    {
        get; set;
    }

    UnityAction testFun
    {
        get; set;
    }
}

public class Lesson8CallInterface : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().DoLuaFile("Main");

        ICCallLua obj = LuaMgr.GetInstance().Global.Get<ICCallLua>("testClass");
        Debug.Log(obj.testint);
        Debug.Log(obj.testbool);
        Debug.Log(obj.teststring);
        Debug.Log(obj.testfloat);
        obj.testFun();

        //接口为引用拷贝,改了值lua中的值也会变化
        obj.testint = 18888;
        ICCallLua obj1 = LuaMgr.GetInstance().Global.Get<ICCallLua>("testClass");
        Debug.Log(obj1.testint);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

LuaTable映射Table

同样使用lua之前的代码

Lua 复制代码
testClass={
	testint=5,
	testbool=true,
	testfloat=4.5,
	teststring="xnbsa",
	testFun=function (  )
		print("243566764")
	end
}

在之前的使用中,我们多次用到LuaTable,在LuaMgr的定义中我们知道,他将其定义为Global,来得到Get里面的变量与函数

但是我们不建议使用LuaTable与LuaFunction,因为他们效率低且会产生垃圾,在不需要使用后要记得销毁

并且他也为深拷贝

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class Lesson9CallLuaTable : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().DoLuaFile("Main");

        //不建议用LuaTable与LauFunction,因为效率低且容易产生垃圾
        //是一种引用对象
        LuaTable table=LuaMgr.GetInstance().Global.Get<LuaTable>("testClass");
        Debug.Log(table.Get<int>("testint"));
        Debug.Log(table.Get<bool>("testbool"));
        Debug.Log(table.Get<float>("testfloat"));
        Debug.Log(table.Get<string>("teststring"));
        table.Get<LuaFunction>("testFun").Call();
        //是引用拷贝
        table.Set("testint", 1949);
        Debug.Log(table.Get<int>("testint"));

        LuaTable table1 = LuaMgr.GetInstance().Global.Get<LuaTable>("testClass");
        Debug.Log(table1.Get<int>("testint"));

        //不用了要记得销毁,会有垃圾
        table.Dispose();
        table1.Dispose();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
相关推荐
lgily-12259 分钟前
Python常用算法
开发语言·python·算法
Tiger Z14 分钟前
R 语言科研绘图第 14 期 --- 柱状图-分组堆叠
开发语言·程序人生·r语言·贴图
前端青山23 分钟前
JavaScript闭包的深度剖析与实际应用
开发语言·前端·javascript·前端框架·ecmascript
凌小添38 分钟前
Python教程丨Python环境搭建 (含IDE安装)——保姆级教程!
开发语言·python·教程
玉面小君1 小时前
深入了解SCPI协议:半导体测试与仪器自动化的核心
c#·仪器仪表·测控技术
代码驿站5201 小时前
PHP语言的数据库编程
开发语言·后端·golang
InSighT__1 小时前
设计模式与游戏完美开发(3)
游戏·设计模式·c#
花菜会噎住2 小时前
Python 模块,包(详解)
开发语言·python
kittygilr2 小时前
matlab中几个取整函数的区别
开发语言·matlab
我不是你的灯笼2 小时前
Go语言的 的垃圾回收(Garbage Collection)基础知识
开发语言·后端·golang