u3d插件xLua[七]例6 Coroutine
讲解xLua例6 Coroutine应该从中学习到什么。可将协程写法分为C#协程lua协程和xLua协程。本文关注的是xLua协程。一.例6 Coroutine代码分析1.1 CoroutineTest.cs用来执行coruntine_test.lua没有业务逻辑using UnityEngine; using XLua; namespace XLuaTest { public class CoroutineTest : MonoBehaviour { LuaEnv luaenv null; // Use this for initialization void Start() { luaenv new LuaEnv(); luaenv.DoString(require coruntine_test); } // Update is called once per frame void Update() { if (luaenv ! null) { luaenv.Tick(); } } void OnDestroy() { luaenv.Dispose(); } } }1.2 coruntine_test.lua业务代码lua侧模拟调用C#协程这里先注释掉一部分代码将demo简化有助于理解这个demo1.cs_coroutine.start相当于c#的StartCoroutine2.coroutine.yield(CS.UnityEngine.WaitForSeconds(1))相当于c#的yield return new WaitForSeconds(1f);local cs_coroutine (require cs_coroutine) local a cs_coroutine.start(function() print(coroutine a started) -- coroutine.yield(cs_coroutine.start(function() -- print(coroutine b stated inside cotoutine a) -- coroutine.yield(CS.UnityEngine.WaitForSeconds(1)) -- print(i am coroutine b) -- end)) --print(coroutine b finish) while true do coroutine.yield(CS.UnityEngine.WaitForSeconds(1)) print(i am coroutine a) end end) -- cs_coroutine.start(function() -- print(stop coroutine a after 5 seconds) -- coroutine.yield(CS.UnityEngine.WaitForSeconds(5)) -- cs_coroutine.stop(a) -- print(coroutine a stoped) -- end)1.3 cs_coroutine.luaLua侧支持协程的module获取脚本组件cs_coroutine_runner用来执行协程方法StartCoroutine和StopCoroutinelocal util require xlua.util local gameobject CS.UnityEngine.GameObject(Coroutine_Runner) CS.UnityEngine.Object.DontDestroyOnLoad(gameobject) local cs_coroutine_runner gameobject:AddComponent(typeof(CS.XLuaTest.Coroutine_Runner)) return { start function(...) return cs_coroutine_runner:StartCoroutine(util.cs_generator(...)) end; stop function(coroutine) cs_coroutine_runner:StopCoroutine(coroutine) end }1.4 Coroutine_Runner.cs空的MonoBehaviour用静态列表导出WaitForSecondsusing UnityEngine; using XLua; using System.Collections.Generic; using System.Collections; using System; namespace XLuaTest { public class Coroutine_Runner : MonoBehaviour { } public static class CoroutineConfig { [LuaCallCSharp] public static ListType LuaCallCSharp { get { return new ListType() { typeof(WaitForSeconds), typeof(WWW) }; } } } }1.5 util.lua协程支持文件local unpack unpack or table.unpack local function async_to_sync(async_func, callback_pos) return function(...) local _co coroutine.running() or error (this function must be run in coroutine) local rets local waiting false local function cb_func(...) if waiting then assert(coroutine.resume(_co, ...)) else rets {...} end end local params {...} table.insert(params, callback_pos or (#params 1), cb_func) async_func(unpack(params)) if rets nil then waiting true rets {coroutine.yield()} end return unpack(rets) end end local function coroutine_call(func) return function(...) local co coroutine.create(func) assert(coroutine.resume(co, ...)) end end local move_end {} local generator_mt { __index { MoveNext function(self) self.Current self.co() if self.Current move_end then self.Current nil return false else return true end end; Reset function(self) self.co coroutine.wrap(self.w_func) end } } local function cs_generator(func, ...) local params {...} local generator setmetatable({ w_func function() func(unpack(params)) return move_end end }, generator_mt) generator:Reset() return generator end local function loadpackage(...) for _, loader in ipairs(package.searchers) do local func loader(...) if type(func) function then return func end end end local function auto_id_map() local hotfix_id_map require hotfix_id_map local org_hotfix xlua.hotfix xlua.hotfix function(cs, field, func) local map_info_of_type hotfix_id_map[typeof(cs):ToString()] if map_info_of_type then if func nil then func false end local tbl (type(field) table) and field or {[field] func} for k, v in pairs(tbl) do local map_info_of_methods map_info_of_type[k] local f type(v) function and v or nil for _, id in ipairs(map_info_of_methods or {}) do CS.XLua.HotfixDelegateBridge.Set(id, f) end --CS.XLua.HotfixDelegateBridge.Set( end xlua.private_accessible(cs) else return org_hotfix(cs, field, func) end end end --和xlua.hotfix的区别是这个可以调用原来的函数 local function hotfix_ex(cs, field, func) assert(type(field) string and type(func) function, invalid argument: #2 string needed, #3 function needed!) local function func_after(...) xlua.hotfix(cs, field, nil) local ret {func(...)} xlua.hotfix(cs, field, func_after) return unpack(ret) end xlua.hotfix(cs, field, func_after) end local function bind(func, obj) return function(...) return func(obj, ...) end end --为了兼容luajitlua53版本直接用|操作符即可 local enum_or_op debug.getmetatable(CS.System.Reflection.BindingFlags.Public).__bor local enum_or_op_ex function(first, ...) for _, e in ipairs({...}) do first enum_or_op(first, e) end return first end -- description: 直接用C#函数创建delegate local function createdelegate(delegate_cls, obj, impl_cls, method_name, parameter_type_list) local flag enum_or_op_ex(CS.System.Reflection.BindingFlags.Public, CS.System.Reflection.BindingFlags.NonPublic, CS.System.Reflection.BindingFlags.Instance, CS.System.Reflection.BindingFlags.Static) local m parameter_type_list and typeof(impl_cls):GetMethod(method_name, flag, nil, parameter_type_list, nil) or typeof(impl_cls):GetMethod(method_name, flag) return CS.System.Delegate.CreateDelegate(typeof(delegate_cls), obj, m) end local function state(csobj, state) local csobj_mt getmetatable(csobj) for k, v in pairs(csobj_mt) do rawset(state, k, v) end local csobj_index, csobj_newindex state.__index, state.__newindex state.__index function(obj, k) return rawget(state, k) or csobj_index(obj, k) end state.__newindex function(obj, k, v) if rawget(state, k) ~ nil then rawset(state, k, v) else csobj_newindex(obj, k, v) end end debug.setmetatable(csobj, state) return state end local function print_func_ref_by_csharp() local registry debug.getregistry() for k, v in pairs(registry) do if type(k) number and type(v) function and registry[v] k then local info debug.getinfo(v) print(string.format(%s:%d, info.short_src, info.linedefined)) end end end return { async_to_sync async_to_sync, coroutine_call coroutine_call, cs_generator cs_generator, loadpackage loadpackage, auto_id_map auto_id_map, hotfix_ex hotfix_ex, bind bind, createdelegate createdelegate, state state, print_func_ref_by_csharp print_func_ref_by_csharp, }二.例6 Coroutine运行展示先打印coroutine a started然后每隔1秒打印i am coroutine a三.例6 Coroutine总结例6 Coroutine应该从中学习到什么1.lua模拟C#的协程写法(比如用StartCoroutine和yield return...)不是一个很简单的事需要一些代码支持(cs_coroutine.lua和util.lua)2.util.lua这种非面向对象table写法阅读时先看return对外提供方法放在return中实现在local function中一定要熟悉和适应(笔者第一个商业xLua项目看到这种写法很不习惯不知道从哪里来的现在知道了可能来自util.lua)3.util.lua中的函数需要熟悉商业xLua项目中有可能lua模拟C#的协程写法不一定用但是去使用util.lua中的函数或者把util.lua放在xLua之外的目录应该知道util.lua不是自研的来自xLua

相关新闻

免费PDF对比工具 diff-pdf 完整实战指南:5 分钟找出两个 PDF 的所有差异

免费PDF对比工具 diff-pdf 完整实战指南:5 分钟找出两个 PDF 的所有差异

免费PDF对比工具 diff-pdf 完整实战指南:5 分钟找出两个 PDF 的所有差异 【免费下载链接】diff-pdf A simple tool for visually comparing two PDF files 项目地址: https://gitcode.com/gh_mirrors/di/diff-pdf 你有没有经历过这样的时刻:一份文…

2026/9/28 4:38:13 阅读更多 →
猿人学 第二题 js 混淆-动态cookie1

猿人学 第二题 js 混淆-动态cookie1

题目地址 https://match.yuanrenxue.cn/match/2 (function() {use strict;var _constructor window.Function.prototype.constructor;window.Function.prototype.constructor function() {if (arguments && typeof arguments[0] string) {if (arguments[0].indexOf(…

2026/9/25 1:57:13 阅读更多 →
如何免费批量下载抖音视频?开源下载工具 douyin-downloader 5 分钟上手

如何免费批量下载抖音视频?开源下载工具 douyin-downloader 5 分钟上手

如何免费批量下载抖音视频?开源下载工具 douyin-downloader 5 分钟上手 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browse…

2026/9/25 17:43:33 阅读更多 →

最新新闻

JavaWeb房地产项目实战:从技术选型到答辩通关指南

JavaWeb房地产项目实战:从技术选型到答辩通关指南

简介:一套基于JavaWeb的房地产信息管理期末大作业源码,面向正在完成Web课程设计、期末实训或需要参考完整业务系统实现的学生与初级开发者。项目采用JSPServlet作为后端核心,包含57个Java源文件,覆盖房源信息、用户管理、数据统计…

2026/10/1 13:36:22 阅读更多 →
scriptc Typed IR 设计解析:泛型单态化与联合类型标签化如何实现(完整指南)

scriptc Typed IR 设计解析:泛型单态化与联合类型标签化如何实现(完整指南)

scriptc Typed IR 设计解析:泛型单态化与联合类型标签化如何实现(完整指南) 【免费下载链接】scriptc TypeScript-to-Native Compiler 项目地址: https://gitcode.com/GitHub_Trending/sc/scriptc scriptc 是一款把 TypeScript / Java…

2026/10/1 13:36:22 阅读更多 →
如何构建一个分钟级行情数据采集程序?从定时请求到可恢复的数据管道

如何构建一个分钟级行情数据采集程序?从定时请求到可恢复的数据管道

一句话结论:分钟级行情采集真正难的不是“每分钟请求一次 API”,而是处理交易时间、重复数据、缺失数据、请求失败和数据落盘,让采集程序能够长期稳定运行。 摘要 分钟级行情数据是很多量化策略的基础,但一个能跑通的 Python 脚本…

2026/10/1 13:36:22 阅读更多 →
人脸识别考勤系统毕设实战:从MTCNN检测到Flask闭环

人脸识别考勤系统毕设实战:从MTCNN检测到Flask闭环

简介:面向计算机相关专业毕业设计的高分项目,以深度学习人脸识别考勤系统为核心,适合正在准备毕设、课程设计或期末大作业的学生使用。项目基于FaceNet算法提取人脸特征,覆盖人脸录入、人脸识别、考勤管理、课堂管理、班级管理、日…

2026/10/1 13:36:22 阅读更多 →
Ubuntu Vulkan安装失败原因与三层架构解析

Ubuntu Vulkan安装失败原因与三层架构解析

1. 为什么在Ubuntu上装Vulkan不是“装个驱动就完事”? 很多人第一次搜“Ubuntu安装vulkan”,点开教程照着敲几行 apt install 命令,终端回车一气呵成,然后兴冲冲跑个 vulkaninfo ——结果卡在 ERROR: [Loader Message] Code…

2026/10/1 13:36:22 阅读更多 →
CNN图像分类实战:猫狗识别项目从数据准备到GUI部署全流程

CNN图像分类实战:猫狗识别项目从数据准备到GUI部署全流程

简介:基于Python与CNN的猫狗识别项目,是一份面向高校学生期末大作业、课程设计与毕业设计的完整源码包。资源共包含6个文件,分别为5个Python脚本与1份Markdown说明文档,其中GUI脚本用于构建图形交互界面,训练脚本负责C…

2026/10/1 13:35:21 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →