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