Unity ToLua 之 C#调用Lua(三)

本文介绍如何使用UnityToLua实现C#与Lua脚本之间的交互,包括访问Lua中的List和Dictionary,操作Lua中的类实例,以及如何在Unity中运行Lua编写的协程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity ToLua 之 C#调用Lua(三)

  • ToLua和XLua不同,XLua相当于映射,而ToLua相当于访问(ToLua中对表的操作都是引用)

一.访问List和Dictionary

  • 设置LuaTable都是按引用设置
testList1 = {10,20,30,40}
testList2 = {false,"zzs",1,6.6}

testDic1 = {
    ["zzs"] = 1,
    ["wy"] = 22,
    ["pnb"] = 333
}
testDic2 = {
    [true] = "zzs",
    [1] = 88.92,
    ["wy"] = false
}
public class Lesson06_ListDic : MonoBehaviour
{
    private void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().Require("Main");

        var luaState = LuaMgr.GetInstance().LuaState;
        
        //List映射
        var luaTable1 = luaState.GetTable("testList1");
        Debug.Log(luaTable1[1]);
        foreach (var item in luaTable1.ToArray())
        {
            Debug.Log(item);
        }

        //引用传递
        luaTable1[1] = 999;
        Debug.Log(luaState.GetTable("testList1")[1]);
        
        Debug.Log("====================");
        var luaTable2 = luaState.GetTable("testList2");
        Debug.Log(luaTable2[1]);
        luaTable2[1] = 888.8;
        foreach (var item in luaTable2.ToArray())
        {
            Debug.Log(item);
        }
        
        Debug.Log("======Dic映射======");
        //Dic映射
        var dic1 = luaState.GetTable("testDic1");
        Debug.Log(dic1["zzs"]);
        Debug.Log(dic1["wy"]);
        Debug.Log(dic1["pnb"]);
        var d = dic1.ToDictTable<string, int>();
        foreach (var item in d)
        {
            Debug.Log(item.Key);
            Debug.Log(item.Value);
        }

        var dic2 = luaState.GetTable("testDic2");
        var dd = dic2.ToDictTable<object, object>();
        //引用传递
        dd["wy"] = 3.14;
        foreach (var item in dd)
        {
            Debug.Log(item.Key);
            Debug.Log(item.Value);
        }
    }
}

二.访问类

testClass = {
    age = 18,
    name = "zzs",
    Eat = function ()
        print("我吃东西")
    end
}
public class Lesson07_Class : MonoBehaviour
{
    void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().Require("Main");
        var luaState = LuaMgr.GetInstance().LuaState;

        var testClass = luaState.GetTable("testClass");
        Debug.Log(testClass["age"]);
        Debug.Log(testClass["name"]);
        var func = testClass.GetLuaFunction("Eat");
        func.Call();
    }
}

三.使用协程

  • 使用协程时需要添加LuaLooper脚本,并初始化才能使用协程
  • 注意,下面的Lua代码的协程写法是ToLua为其提供的正常的Lua和XLua不能这么写
local cor = nil

StartDelay = function()
    cor = coroutine.start(Delay)
end

Delay = function()
    local a = 1
    while true do
        print(a)
        coroutine.wait(1)
        a = a + 1
        if a > 5 then
            StopDelay()
            break
        end
    end
end

StopDelay = function()
    coroutine.stop(cor)
end
public class Lesson08_Coroutine : MonoBehaviour
{
    private void Start()
    {
        LuaMgr.GetInstance().Init();
        LuaMgr.GetInstance().Require("Main");
        var luaState = LuaMgr.GetInstance().LuaState;

        var func = luaState.GetFunction("StartDelay");
        func.Call();
    }
}

在这里插入图片描述

### C# 调用 Lua 的工作原理 在 Unity 中通过 C# 调用 Lua 主要依赖于第方库如 XLuaToLua 来桥接两种语言之间的交互。XLua 提供了一种机制使得可以在 C# 环境下加载并执行 Lua 文件中的代码。 当使用 `require` 函数引入其他 Lua 模块时,例如: ```lua print("主Lua启动") require("Test") -- 加载 Test.lua 文件[^1] ``` 这行代码会在 Lua 运行环境中查找名为 "Test" 的模块,并尝试加载它。如果是在 Unity 下运行,则会由 XLua 处理这个请求并将对应的 Lua 文件映射到实际路径上进行解析和执行。 对于 C#Lua 之间更深层次的互操作性来说,通常涉及到以下几个方面的工作原理: #### 数据交换与类型转换 为了允许两个同编程环境间的数据传递,必须定义一套双方都能理解的数据结构以及相应的序列化/反序列化逻辑。XLua 实现了基本数据类型的自动转换功能,同时也支持自定义类对象作为参数传入传出 Lua 函数调用。 #### 方法绑定 为了让 Lua 可以访问 C# 定义的方法或者属性,需要建立一种方式来注册这些成员给 Lua 使用。XLua 支持静态方法、实例方法甚至事件监听器等多种形式的方法暴露给 Lua 层面去调用。同样地,在 Lua 编写的函数也可以被 C# 所回调,形成双向通信的能力。 #### 性能优化策略 考虑到频繁跨越边界可能会带来性能开销,因此框架内部采取了一些措施减少必要的切换次数。比如缓存已经编译好的 Lua chunk(即一段完整的可执行单元),避免重复解释相同的源码;另外还提供了批量提交指令的功能以便一次性完成多个操作而需要多次上下文切换。 ```csharp // 注册C#方法给Lua使用的一个简单例子 public class Example : MonoBehaviour { void Start() { // 假设这里初始化好了LuaEnv环境变量env env.Global.SetAsFunction("PrintFromCS", PrintMessage); } public static void PrintMessage(string msg){ Debug.Log(msg); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值