Unity中自定义协程的简单实现

在 Unity 中,协程(Coroutine)是一种非常强大的工具,它允许我们在不阻塞主线程的情况下,将代码的执行分成多个步骤,在不同的帧中执行。

Unity中协程实现原理
迭代器与状态机:本质上是基于C#的迭代器和状态机实现的。迭代器允许函数暂停和恢复执行,协程函数使用 yield return 语句暂停,保存当前状态,下次被调用时从暂停处继续。Unity在底层通过状态机管理协程状态,记录执行位置和局部变量等。
消息循环与时间管理:Unity的消息循环在每一帧检查协程状态。当协程 yield return 一个条件或等待时间时,Unity记录该条件,在后续帧中检查条件是否满足,满足则恢复协程执行。
执行队列与调度:Unity维护协程执行队列,按添加顺序或优先级调度协程。协程加入队列后,等待Unity根据帧循环和条件判断调度执行。

要实现自定义协程需用到一个暂停指令和协程的MoveNext方法:
1.YieldInstruction:用于实现协程的暂停指令,所有具体的暂停指令都需要继承自该类,并实现IsDone方法,用于判断暂停是否完成。
2.MoveNext方法:通过不断调用该方法,检测协程的暂停条件是否成立,如果条件成立,协程从暂停处继续执行,否则协程不会继续执行。

定义一个暂停指令基类:

public abstract class YieldInstruction
{public abstract bool IsDone();
}

定义一个暂停指令:重写IsDone函数

public class WaitForFrames : YieldInstruction
{public override bool IsDone(){remainingFrames--;return remainingFrames <= 0;}
}

 自定义一个协程类:它需要包含暂停指令、需要执行的迭代器函数、还要实现一个MoveNext函数,具体实现如下:

    public bool MoveNext(){//首先判断暂停指令是否存在if (currentYield != null){if (!currentYield.IsDone()){// 当前 YieldInstruction 未完成,继续等待return true;}// 当前 YieldInstruction 完成,重置currentYield = null;}//如果迭代器的MovenNext方法返回true则协程等待if (routine.MoveNext()){currentYield = routine.Current as YieldInstruction;return true;}// 协程执行完毕return false;}

自定义调度器: 需要实现StartCoroutine,StopCoroutine和Update函数

    // 存储待执行的协程列表private List<CustomCoroutine> coroutines = new List<CustomCoroutine>();// 启动一个协程public CustomCoroutine StartCoroutine(IEnumerator routine){CustomCoroutine coroutine = new CustomCoroutine(routine);coroutines.Add(coroutine);return coroutine;}// 更新协程调度器,需要在每一帧调用public void Update(){for (int i = coroutines.Count - 1; i >= 0; i--){coroutines[i].MoveNext();}}public void StopCoroutine(CustomCoroutine routine){coroutines.Remove(routine);}public void StopAllCoroutine(){coroutines.Clear();}

调用:

CustomCoroutineScheduler scheduler = new CustomCoroutineScheduler();void Start(){// 启动一个协程scheduler.StartCoroutine(TestCoroutine());}void Update(){scheduler.Update();}IEnumerator TestCoroutine(){Debug.Log("Coroutine started");yield return new WaitForFrames(3);Debug.Log("Waited for 3 frames");Debug.Log("Coroutine ended");}

 结果:

其他有用的链接:

KarnageUnity/CustomCoroutine: Two C# classes demonstrating how Unity implements Coroutines (github.com)

gohbiscuit/UnityCustomCoroutine: Unity Custom Coroutine class can be use to handle multiple or nested coroutine (github.com)

Ellpeck/Coroutine: A simple implementation of Unity's Coroutines to be used for any C# project (github.com)

utamaru/unity3d-extra-yield-instructions:Unity3D 协程的其他自定义 yield 指令 (github.com) 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/70941.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot过滤器链:从入门到精通

文章目录 一、过滤器链是什么&#xff1f;二、为什么需要过滤器链&#xff1f;三、Spring Boot中的过滤器链是如何工作的&#xff1f;&#xff08;一&#xff09;过滤器的生命周期&#xff08;二&#xff09;过滤器链的执行流程 四、如何在Spring Boot中定义自己的过滤器&#…

【博客之星】GIS老矣尚能饭否?WebGIS项目实战经验与成果展示

目录 一、最前面的话 二、前言 1、关于“夜郎king” 3、GIS的“老骥伏枥” 4、WebGIS的“新程启航” 三、WebGIS技术简介 1、前、后技术简介 2、系统功能架构 四、WebGIS项目应用效果 1、应急灾害 2、交通运输 3、智慧文旅 4、其它项目 五、未来与展望 1、云计算…

游戏内常见加密

加密只是增大破解难度&#xff0c;没法说绝对安全&#xff0c;避免过度加密导致性能消耗过大。 通用算法库 lua的加密算法库&#xff1a;https://github.com/somesocks/lua-lockbox/tree/master 比如通信协议就用到里面一些算法cry.encrypt 算法优劣&#xff1a;AES加解密-CBC…

C++中什么时候用. 什么时候用->

学了一年C今天出了一个大岔子&#xff0c;因为太久没有做链表类型题目了&#xff0c;并且STL用惯了今天遇到一题&#xff0c;写的时候发现完全不对劲&#xff0c;搞慌了&#xff0c;首先我们看题目 2. 两数相加 再看我第一次的解答&#xff0c;先不论结果对不对 错的行为有很多…

本地部署DeepSeek Nodejs版

目录 1.下载 Ollama 2.下载DeepSeek模型 3.下载 ollama.js 1.下载 Ollama https://ollama.com/ 下载之后点击安装&#xff0c;等待安装成功后&#xff0c;打开cmd窗口&#xff0c;输入以下指令&#xff1a; ollama -v 如果显示了版本号&#xff0c;则代表已经下载成功了。…

UE5中的快捷键汇总

以下是Unreal Engine 5&#xff08;UE5&#xff09;中一些常用的快捷键大全&#xff0c;涵盖编辑器操作、视口导航、蓝图编辑等多个方面(会持续补充作为笔记存在)&#xff1a; 通用快捷键 快捷键功能Ctrl S保存当前关卡Ctrl Shift S保存所有Ctrl Z撤销Ctrl C复制Ctrl V…

java项目之足球联赛管理系统源码(ssm+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的足球联赛管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 足球联赛管理系统的主要使用者…

HttpServletRequest 作用

HttpServletRequest 接口在 Java Servlet API 中扮演着至关重要的角色&#xff0c;它是 Servlet 处理客户端 HTTP 请求的核心对象。 每次客户端&#xff08;例如浏览器&#xff09;向服务器发送一个 HTTP 请求时&#xff0c;Servlet 容器&#xff08;例如 Tomcat&#xff09;都…

【Kubernetes的SpringCloud最佳实践】Spring Cloud netflix 能否被K8s资源完全替代?

在部署Spring Cloud微服务到Kubernetes&#xff08;K8s&#xff09;时&#xff0c; Spring Cloud netflix 是否需要完全替代&#xff1f;或者可以部分替代&#xff0c;结合使用&#xff1f; 例如&#xff0c;服务发现和负载均衡可以交给K8s处理&#xff0c; 但某些功能如API网关…

SQL 大厂面试题目(由浅入深)

今天给大家带来一份大厂SQL面试覆盖&#xff1a;基础语法 → 复杂查询 → 性能优化 → 架构设计&#xff0c;大家需深入理解执行原理并熟悉实际业务场景的解决方案。 1. 基础查询与过滤 题目&#xff1a;查询 employees 表中所有薪资&#xff08;salary&#xff09;大于 10000…

【C】链表算法题7 -- 环形链表||

leetcode链接https://leetcode.cn/problems/linked-list-cycle-ii/description/ 问题描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到…

uniapp开发h5部署到服务器

1.发行>网站-PC Web或手机H5&#xff08;仅适用于uniapp&#xff09; 2.填写网站域名 3.编译成功后会生成一个unpackage文件夹找到下面的h5 4.接下来会使用一个工具把h5里面的文件放到服务器上面&#xff08;WinSCP使用其他能部署的工具也行&#xff09; 5.登录 6.登录成功后…

PyTorch Lightning Trainer介绍

PyTorch Lightning 的 Trainer 是框架的核心类&#xff0c;负责自动化训练流程、分布式训练、日志记录、模型保存等复杂操作。通过配置参数即可快速实现高效训练&#xff0c;无需手动编写循环代码。以下是详细介绍和使用示例&#xff1a; Trainer 的核心功能 自动化训练循环 自…

亚信安全正式接入DeepSeek

亚信安全致力于“数据驱动、AI原生”战略&#xff0c;早在2024年5月&#xff0c;推出了“信立方”安全大模型、安全MaaS平台和一系列安全智能体&#xff0c;为网络安全运营、网络安全检测提供AI技术能力。自2024年12月DeepSeek-V3发布以来&#xff0c;亚信安全人工智能实验室利…

小白零基础如何搭建CNN

1.卷积层 在PyTorch中针对卷积操作的对象和使用的场景不同&#xff0c;如有1维卷积、2维卷积、 3维卷积与转置卷积&#xff08;可以简单理解为卷积操作的逆操作&#xff09;&#xff0c;但它们的使用方法比较相似&#xff0c;都可以从torch.nn模块中调用&#xff0c;需要调用的…

视频基础操作

1.1. 例子 读取mp4格式的视频&#xff0c;将每一帧改为灰度图&#xff0c;并且打上水印&#xff08;“WaterMark”&#xff09;,并将其输出保存为out.mp4&#xff0c;在这个例子中可以看到视频读取&#xff0c;每帧数据处理&#xff0c;视频保存的整体流程简单示例 import cv…

21vue3实战-----git husky和git commit规范

21vue3实战-----git husky和git commit规范 1.husky工具1.1目的1.2如何做到这一点?1.3步骤 2.git commit规范2.1使用Commitizen自动生成规范格式供选择2.2代码提交风格2.3代码提交验证 之前在https://blog.csdn.net/fageaaa/article/details/145474065文章中已经讲了在vue项目…

Unity3D 类MOBA角色控制器 开箱即用

Github: Unity3D-MOBA-Character-Controller 觉得好用麻烦点个Star感谢&#xff01;

Kafka 的消费offset原来是使用ZK管理,现在新版本是怎么管理的?

目录 基于 ZooKeeper 管理消费 offset 原理 缺点 新版本基于内部主题管理消费 offset 原理 优点 示例代码(Java) 在 Kafka 早期版本中,消费者的消费偏移量(offset)是存储在 ZooKeeper 中的,但由于 ZooKeeper 并不适合高频读写操作,从 Kafka 0.9 版本开始,消费偏…

使用 Nginx 搭建代理服务器(正向代理 HTTPS 网站)指南

在网络应用中&#xff0c;代理服务器是用于中转用户请求和服务端响应的工具。正向代理主要用于客户端与外部服务器之间的访问代理&#xff0c;帮助客户端隐藏其 IP 地址或访问受限资源。本文将详细介绍如何使用 Nginx 搭建正向代理服务器&#xff0c;特别是针对 HTTPS 网站的代…