xLua中C#调用Lua

C#调用Lua

一.前提

这里使用的是XLua框架,需要提前配置xlua,设置加载器路径;

可以参考之前的Blog:《xlua入门基础》

二.C#调用Lua全局变量

lua中所有的全局变量都会存在一个表中,对应xLua中的Global,通过lua解释器返回出来;

通过Global的方法Get<类型>(key)调用;

--Lua代码
num = 199
name = "littlePerilla"
hp = 2112.121
active = true

//c#代码
private void Start()
{
	XluaEnv.I.DoString("CSharpCallVariable");
	LuaTable golbal = XluaEnv.I.Golbal();

	int id = golbal.Get<int>("num");
	string name = golbal.Get<string>("name");
	float hp = golbal.Get<float>("hp");
	bool active = golbal.Get<bool>("active");

	Debug.Log(id + "," + name + "," + hp + "," + active);
}

调用lua中局部变量,通过table调用;

三.C#调用Lua全局方法

调用lua中方法和调用变量方式相同,返回值为委托类型;

1.无参数方法

--Lua代码
func = function ()
	print("lua函数")
end

 Action act1 = golbal.Get<Action>("func");
 act1();

2.带参数方法

--Lua代码
func2 = function(mName)
	print(mName)
end

[CSharpCallLua]
public delegate void Func2(string name);

private void Start()
{
	Func2 act3 = golbal.Get<Func2>("func2");
	act3("littlePerilla");
}

3.多返回值

--Lua代码
func1 = function()
	return 1,2,3
end	

1)使用委托

[CSharpCallLua]
public delegate void Func(out int a, out int b, out int c);

private void Start()
{
	Func act3 = golbal.Get<Func>("func1");
    int a,b,c;
	act3(out a,out b,out c);
}

2)使用LuaFunction

LuaFunction act2 = golbal.Get<LuaFunction>("func1");
object[] objs = act2.Call();
foreach (var obj in objs)
{
    Debug.Log(obj);
}

坑:这里使用委托必须要加[CSharpCallLua]特性,但是有时候加了也会失效,可能是xlua版本和Unity版本兼容问题;

四.C#调用Lua表

Lua中的table相当于C#中的类,调用表也就是调用类;

--lua代码
tabe = {}

tabe.name = "littlePerilla"
tabe.hp = 100

tabe.attack = function (self)
	return "展开了攻击"
end

tabe.jump = function(self)
	self = tabe
	print(self.name.."跳了起来")
end

1.通过Class映射

[CSharpCallLua]
public class Role
{
    [CSharpCallLua]
    public delegate string Func1();
    [CSharpCallLua]
    public delegate void Func2();
    
    public string name;
    public int hp;
    public Func1 attack;
    public Func2 jump;
}

public class CSharpCallTable:MonoBehaviour
{
    private void Start()
    {
        XluaEnv.I.DoString("CSharpCallTable");
        LuaTable global = XluaEnv.I.Golbal();
        
        //通过table和c#中类映射来调用
	 Role core = global.Get<Role>("tabe");
	 core.name = "SuperPerilla";
	 Debug.Log(core.name+","+core.hp);
	 Debug.Log(core.attack());
	 core.jump();
    }
}

2.通过LuaTable

public class CSharpCallTable:MonoBehaviour
{
    private void Start()
    {
        XluaEnv.I.DoString("CSharpCallTable");
        LuaTable global = XluaEnv.I.Golbal();
        
        //通过C#中luatable类型调用
	 LuaTable core2 = global.Get<LuaTable>("tabe");
	 core2.Set<string, string>("name", "SuperPerilla"); 
	 Func<string> osp = core2.Get<Func<string>>("attack");
	 Debug.Log(osp());
	 Action jump = core2.Get<Action>("jump");
	 jump();
    }
}

坑:这两个打印结果明显不同,通过类映射调用,修改类对象的字段后,再调用lua方法,方法中使用了该字段,发现字段值并没有改变,这应该是和lua中self的赋值有关系;

建议使用LuaTable来调用lua中的table;

但是据说通过结构体映射会减少Lua代码调用的GC,需要加上特性[GCOptimize];

posted @ 2021-10-11 14:57  小紫苏  阅读(1679)  评论(0编辑  收藏  举报