22.Lua调用Unity的协同程序

22.Lua调用CSharp-协同程序


22.1 知识点

准备工作

启动Lua脚本

LuaManager.Instance.Init();
LuaManager.Instance.DoLuaFile("Lesson22_Lua调用CSharp_协同程序");

创建一个 MonoBehaviour 脚本

public class Lesson22_Test : MonoBehaviour
{

}

定义别名,新建空物体并添加一个 MonoBehaviour 脚本

-- 别名
GameObject = CS.UnityEngine.GameObject
WaitForSeconds = CS.UnityEngine.WaitForSeconds
Input = CS.UnityEngine.Input
KeyCode = CS.UnityEngine.KeyCode

-- 场景中新建一个空物体 挂一个 MonoBehaviour 脚本 准备通过个 MonoBehaviour 脚本来开启协程
local obj = GameObject("协程测试对象")
local test = obj:AddComponent(typeof(CS.Lesson22_Test))

准备协程相关

-- xlua 提供的工具表 xlua.util 要 require 调用 xlua.util 后才使用 Unity 的协程相关
util = require("xlua.util")

-- 希望用来被开启的协程函数 
-- lua 中 不能直接使用 C# 协程返回语法 yield return
-- 而是使用 lua 协程返回语法 coroutine.yield()
myFunction = function()
    local i = 1
    while true do
        coroutine.yield(WaitForSeconds(1))
        print(i)
        i = i + 1
    end
end

启动协程

-- 不能直接将 lua 函数传入到开启协程方法 StartCoroutine 中 会报错
-- myCoroutine = test:StartCoroutine(myFunction)--报错

-- 需要先调用 xlua.util 中的 cs_generator(lua 函数) 再传入到开启协程方法 StartCoroutine 中
-- 可以理解为 util.cs_generator(lua 函数) 会返回一个 IEnumerator 方法
-- 用一个变量接住 作为协程对象
myCoroutine = test:StartCoroutine(util.cs_generator(myFunction))

停止协程

-- 和 Unity 一样的 StopCoroutine 方法 传入协程对象 停止协程
test:StopCoroutine(myCoroutine)

制作按空格开启协程,再次按空格停止协程的功能,创建 Lua 的帧更新函数,在 Unity 中调用:

-- 制作按空格开启协程 再次按空格停止协程的功能
function Update()
    if Input.GetKeyDown(KeyCode.Space) then
        -- 检测到空格键按下
        if myCoroutine ~= nil then
            -- 如果协程正在运行,停止协程
            print("停止协程")
            -- 和 Unity 一样的 StopCoroutine 方法 传入协程对象 停止协程
            test:StopCoroutine(myCoroutine)
            myCoroutine = nil
        else
            -- 如果协程未运行,重新启动协程
            print("启动协程")
            myCoroutine = test:StartCoroutine(util.cs_generator(myFunction))
        end
    end
end

在 C# 中调用 Lua 的帧更新函数:

LuaFunction luaUpdate;

void Start()
{
    // Xlua 获取函数 尽量少用 会产生一些垃圾
    luaUpdate = LuaManager.Instance.Global.Get<LuaFunction>("Update");
}

private void Update()
{
    // LuaFunction 函数通过 Call 方法调用
    luaUpdate.Call(); // 我是 Lua 无参无返回值函数
}

22.2 知识点代码

Lesson22_Lua调用CSharp_协同程序.lua

print('我是Lua脚本 Lesson22_Lua调用CSharp_协同程序')

--别名
GameObject = CS.UnityEngine.GameObject
WaitForSeconds = CS.UnityEngine.WaitForSeconds
Input = CS.UnityEngine.Input
KeyCode = CS.UnityEngine.KeyCode

--场景中新建一个空物体 挂一个MonoBehaviour脚本 准备通过个MonoBehaviour脚本来开启协程
local obj = GameObject("协程测试对象")
local test = obj:AddComponent(typeof(CS.Lesson22_Test))

print("**********知识点一 准备协程相关************")

--xlua提供的工具表xlua.util 要require调用xlua.util后 才使用Unity的协程相关
util = require("xlua.util")

--希望用来被开启的协程函数 
--lua中 不能直接使用 C#协程返回语法 yield return
--而是使用 lua协程返回语法 coroutine.yield()
myFunction = function()
    local i = 1
    while true do
        coroutine.yield(WaitForSeconds(1))
        print(i)
        i = i + 1
    end
end


print("**********知识点二 启动协程************")

--不能直接将lua函数传入到开启协程方法StartCoroutine中 会报错
-- myCoroutine = test:StartCoroutine(myFunction)--报错

--需要先调用 xlua.util中的cs_generator(lua函数) 再传入到开启协程方法StartCoroutine中
--可以理解为util.cs_generator(lua函数)会返回一个IEnumerator方法
--用一个变量接住 作为协程对象
myCoroutine = test:StartCoroutine(util.cs_generator(myFunction))


print("**********知识点三 停止协程************")
--和Unity一样的StopCoroutine方法 传入协程对象 停止协程
test:StopCoroutine(myCoroutine)

--制作按空格开启协程 再次按空格停止协程的功能

function Update()
    if Input.GetKeyDown(KeyCode.Space) then
        -- 检测到空格键按下
        if myCoroutine ~= nil then
            -- 如果协程正在运行,停止协程
            print("停止协程")
            --和Unity一样的StopCoroutine方法 传入协程对象 停止协程
            test:StopCoroutine(myCoroutine)
            myCoroutine = nil
        else
            -- 如果协程未运行,重新启动协程
            print("启动协程")
            myCoroutine = test:StartCoroutine(util.cs_generator(myFunction))
        end
    end
    
end

Lesson22_Lua调用CSharp_协同程序

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;

public class Lesson22_Lua调用CSharp_协同程序 : MonoBehaviour
{
    LuaFunction luaUpdate;

    void Start()
    {
        LuaManager.Instance.Init();
        LuaManager.Instance.DoLuaFile("Lesson22_Lua调用CSharp_协同程序");

        //Xlua获取函数 尽量少用 会产生一些垃圾
        luaUpdate = LuaManager.Instance.Global.Get<LuaFunction>("Update");
    }

    private void Update()
    {

        //LuaFunction函数通过Call方法调用
        luaUpdate.Call();// 每帧转调 Lua 全局 Update
    }
}

public class Lesson22_Test : MonoBehaviour
{

}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏