Unity--协程--Coroutine

Unity–协程–Coroutine

1. 协程的基本概念

  1. 基本概念:不是线程,将代码按照划分的时间来执行,这个时间可以是具体的多少秒,也可以是物理帧的时间,也可以是一帧的绘制结束的时间。

  2. 协程的写法:通过返回IEnumerator的函数实现,使用yield return语句暂停执行。

  3. 等待时间:使用WaitForSeconds等待特定时间,在Update和LateUpdate之间执行

  4. 其他等待选项WaitForEndOfFrame等待当前帧结束,可以用来截取画面,游戏帧画面分析WaitForFixedUpdate等待下一个固定物理帧更新时执行。

    下一帧执行: yield return 数字yield return null; 在Update和LateUpdate之间执行

    public IEnumerator MyCoroutine(int i, string str, float t)
    {print(i);// 返回值IEumerator yield return 来分时函数,即等待多少秒后继续执行函数yield return new WaitForSeconds(5.0f);                // 等待5s后执行print(str);yield return new WaitForSeconds(3.0f);print(t);yield return new WaitForEndOfFrame();               // 等待当前帧绘制完毕后执行print(t);yield return new WaitForFixedUpdate();              // 直到下一个固定更新周期到了执行print(i);// ...
    }
    

2. 开启协程

  1. 开启方法:使用StartCoroutine方法。

  2. 开启方式:可以直接传递方法名或先获取IEnumerator对象再传递。

    	// 2.1 不同于文文普通的函数调用来开启协程// MyCoroutine(3, "不能使用普通方法调用开启/协程", 5.0f);// 2.2 开启方法1public void StartMyCoroutine1(){StartCoroutine(MyCoroutine(1, "开启协程1", 1.0f));}// 2.3 开启方法2public void StartMyCoroutine2(){IEnumerator ie =  MyCoroutine(1, "开启协程2", 1.0f);StartCoroutine(ie);}// 2.4 开启多个协程public void StartMyCoroutine3(){// 开启协程后保留写出对象c1 = StartCoroutine(MyCoroutine(1, "多个协程1", 1.0f));c2 = StartCoroutine(MyCoroutine(1, "多个协程2", 1.0f));c3 = StartCoroutine(MyCoroutine(1, "多个协程3", 1.0f));}
    

3. 关闭协程

  1. 关闭所有协程:使用StopAllCoroutines

  2. 关闭特定协程:使用StopCoroutine,可以传递IEnumerator对象、协程的引用或方法名。

    	// 1. 关闭所有协程public void CloseAllCoroutine(){StopAllCoroutines();}// 2. 关闭指定协程public void CloseSpecialCoroutine(){StopCoroutine(c1);// StopCoroutine(IEnumerator routine); 通过IEnumerator关闭              // StopCoroutine(Coroutine routine);   通过协程名称关闭// StopCoroutine(string methodName);   通过协程函数名关闭}
    

    关闭指定协程的方法有很多,一般不使用协程函数名关闭

    StopCoroutine(IEnumerator routine); 通过IEnumerator关闭

    StopCoroutine(Coroutine routine); 通过协程名称关闭
    StopCoroutine(string methodName); 通过协程函数名关闭

4. 提前跳出协程

使用yield break在满足条件时提前终止执行。

// 提前跳出协程public void BreakCoroutine(){IEnumerator MyNewCoroutine(){Debug.Log("开始执行协同程序");// 执行一些操作yield return new WaitForSeconds(1.0f);Debug.Log("协同程序执行了一秒");// 在这里,我们检查一个条件if (SomeCondition()){Debug.Log("满足条件,提前结束协同程序");yield break; // 提前终止协同程序}// 如果上面的条件不满足,这将不会执行yield return new WaitForSeconds(1.0f);Debug.Log("协同程序又执行了一秒");}StartCoroutine(MyNewCoroutine());}bool SomeCondition(){// 这里是条件的逻辑return true; // 例如,始终返回 true 来终止协同程序}

5. 特殊情况

协程当组件或游戏对象失效或者失活的时候怎么办???

协程开启后

  1. ​ 组件和物体销毁,协程不执行
  2. ​ 物体失活协程不执行,组件失活协程执行

6.建议

  • 协程的使用:适用于处理异步操作和分步骤执行任务,如动画、加载资源。
  • 性能考虑:比多线程轻量,适合游戏开发中的非阻塞操作。
  • 条件检查:在协程中使用条件检查可以灵活控制流程。
  • 资源管理:在使用协程加载资源时,注意资源的释放和内存管理。

7.完成测试代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CoroutineTest : MonoBehaviour
{Coroutine c1;Coroutine c2;Coroutine c3;// 协程程序// 1. 协程的使用// 1.1 协程的写法public IEnumerator MyCoroutine(int i, string str, float t){print(i);// 返回值IEumerator yield return 来分时函数,即等待多少秒后继续执行函数yield return new WaitForSeconds(5.0f);              // 等待5s后执行print(str);yield return new WaitForSeconds(3.0f);print(t);//yield return new WaitForEndOfFrame();               // 等待当前帧绘制完毕后执行//print(t);//yield return new WaitForFixedUpdate();              // 直到下一个固定更新周期到了执行//print(i);}// 2. 开启协程// 2.1 不同用普通的函数调用来开启协程// MyCoroutine(3, "不能使用普通方法调用开启/协程", 5.0f);// 2.2 开启方法1public void StartMyCoroutine1(){StartCoroutine(MyCoroutine(1, "开启协程1", 1.0f));}// 2.3 开启方法2public void StartMyCoroutine2(){IEnumerator ie =  MyCoroutine(1, "开启协程2", 1.0f);StartCoroutine(ie);}// 2.4 开启多个协程public void StartMyCoroutine3(){// 开启协程后保留写出对象c1 = StartCoroutine(MyCoroutine(1, "多个协程1", 1.0f));c2 = StartCoroutine(MyCoroutine(1, "多个协程2", 1.0f));c3 = StartCoroutine(MyCoroutine(1, "多个协程3", 1.0f));}// 3. 关闭协程public void CloseAllCoroutine(){StopAllCoroutines();}// 4. 关闭指定协程public void CloseSpecialCoroutine(){StopCoroutine(c1);StopCoroutine(c2);StopCoroutine(c3);// StopCoroutine(IEnumerator routine); 通过IEnumerator关闭              // StopCoroutine(Coroutine routine);   通过协程名称关闭// StopCoroutine(string methodName);   通过协程函数名关闭}// 5. 提前跳出协程public void BreakCoroutine(){IEnumerator MyNewCoroutine(){Debug.Log("开始执行协同程序");// 执行一些操作yield return new WaitForSeconds(1.0f);Debug.Log("协同程序执行了一秒");// 在这里,我们检查一个条件if (SomeCondition()){Debug.Log("满足条件,提前结束协同程序");yield break; // 提前终止协同程序}// 如果上面的条件不满足,这将不会执行yield return new WaitForSeconds(1.0f);Debug.Log("协同程序又执行了一秒");}StartCoroutine(MyNewCoroutine());}bool SomeCondition(){// 这里是条件的逻辑return true; // 例如,始终返回 true 来终止协同程序}void Start(){StartMyCoroutine1();StartMyCoroutine2();StartMyCoroutine3();CloseSpecialCoroutine();BreakCoroutine();CloseAllCoroutine();}
}

8.应用:计时器(顺序计时和倒计时)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class TimeCounter : MonoBehaviour
{IEnumerator TimeConter(int sumSeconds, bool sequence){int time = 0;if (sequence){while (true){// 顺序计时// 抵达终止时间if (time >= sumSeconds){Debug.Log(sumSeconds + "s 时间到(顺序计时)");yield break;}// 延迟一秒执行yield return new WaitForSeconds(1.0f);// 修改时间time++;// 打印时间Debug.Log(time);}}else {// 倒计时time = sumSeconds;while (true){if (time <= 0){Debug.Log(sumSeconds + "s 时间到(倒序计时)");yield break;}Debug.Log(time--);yield return new WaitForSeconds(1.0f);}}}private void Start(){// 开启计时器协程Coroutine c1 = StartCoroutine(TimeConter(10, true));Coroutine c2 = StartCoroutine(TimeConter(3, false));}}

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

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

相关文章

Golang | Leetcode Golang题解之第205题同构字符串

题目&#xff1a; 题解&#xff1a; func isIsomorphic(s, t string) bool {s2t : map[byte]byte{}t2s : map[byte]byte{}for i : range s {x, y : s[i], t[i]if s2t[x] > 0 && s2t[x] ! y || t2s[y] > 0 && t2s[y] ! x {return false}s2t[x] yt2s[y] …

python 查找轮廓

在Python中&#xff0c;查找图像的轮廓通常使用OpenCV库。以下是一个简单的示例代码&#xff0c;展示了如何使用OpenCV来查找并绘制图像的轮廓&#xff1a; pythonimport cv2 import numpy as np# 读取图像 image cv2.imread(your_image.jpg, 0) # 请将your_image.jpg替换为您…

设备树下的 platform 驱动编写

设备树下的 platform 驱动编写 设备树下的 platform 驱动简介 platform 驱动框架分为总线、设备和驱动&#xff0c;其中总线不需要我们这些驱动程序员去管理&#xff0c;这个是 Linux 内核提供的&#xff0c;我们在编写驱动的时候只要关注于设备和驱动的具体实现即可。在没有…

《昇思25天学习打卡营第6天 | 函数式自动微分》

《昇思25天学习打卡营第6天 | 函数式自动微分》 目录 《昇思25天学习打卡营第6天 | 函数式自动微分》函数式自动微分简单的单层线性变换模型函数与计算图微分函数与梯度计算Stop Gradient 函数式自动微分 神经网络的训练主要使用反向传播算法&#xff0c;模型预测值&#xff0…

建站小记:迁移域名DNS到CloudFlare

CloudFlare一直有赛博菩萨之称&#xff0c;据说用它做DNS解析服务又快又好又免费&#xff0c;还能防DDOS攻击&#xff0c;并且可以提供页面访问统计功能。 正好我博客网页打开略卡顿&#xff0c;所以决定将自己的DNS解析迁移到CloudFlare。 1.登录CF控制台&#xff0c;添加自己…

LeetCode-刷题记录-二分法合集(本篇blog会持续更新哦~)

一、二分查找概述 二分查找&#xff08;Binary Search&#xff09;是一种高效的查找算法&#xff0c;适用于有序数组或列表。&#xff08;但其实只要满足二段性&#xff0c;就可以使用二分法&#xff0c;本篇博客后面博主会持续更新一些题&#xff0c;来破除一下人们对“只有有…

(已解决)Adobe Flash Player已不再受支持

文章目录 前言解决方案 前言 一般来说&#xff0c;很少遇到官方网站使用Adobe Flash Player来进行录用名单公示了。但是&#xff0c;今天就偏偏遇到一次&#xff0c; 用谷歌浏览器打不开&#xff0c; 点了没有反应&#xff0c;用其他的浏览器&#xff0c;例如windows自带的那…

Golang | Leetcode Golang题解之第207题课程表

题目&#xff1a; 题解&#xff1a; func canFinish(numCourses int, prerequisites [][]int) bool {var (edges make([][]int, numCourses)indeg make([]int, numCourses)result []int)for _, info : range prerequisites {edges[info[1]] append(edges[info[1]], info[0]…

数据结构:期末考 第六次测试(总复习)

一、 单选题 &#xff08;共50题&#xff0c;100分&#xff09; 1、表长为n的顺序存储的线性表&#xff0c;当在任何位置上插入或删除一个元素的概率相等时&#xff0c;插入一个元素所需移动元素的平均个数为&#xff08; D &#xff09;.&#xff08;2.0&#xff09; A、 &am…

在node环境使用MySQL

什么是Sequelize? Sequelize是一个基于Promise的NodeJS ORM模块 什么是ORM? ORM(Object-Relational-Mapping)是对象关系映射 对象关系映射可以把JS中的类和对象&#xff0c;和数据库中的表和数据进行关系映射。映射之后我们就可以直接通过类和对象来操作数据表和数据了, 就…

join()方法——连接字符串、元组、列表和字典

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 join()方法用于连接字符串数组。将字符串、元组、列表中的元素以指定的字符&#xff08;分隔符&#xff09;连接生成一个新的字符串&#…

喜报 | 极限科技获得北京市“创新型”中小企业资格认证

2024年6月20日&#xff0c;北京市经济和信息化局正式发布《关于对2024年度4月份北京市创新型中小企业名单进行公告的通知》&#xff0c;极限数据&#xff08;北京&#xff09;科技有限公司凭借其出色的创新能力和卓越的企业实力&#xff0c;成功获得“北京市创新型中小企业”的…

学会python——在excel中写入数据(python实例十三)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3 .想Excel中写入数据 3.1 代码构思 3.2 代码实例 3.3 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的…

数据结构算法之B树

一、绪论 1.1 数据结构的概念和作用 1.2 B树的起源和应用领域 二、B树的基本原理 2.1 B树的定义和特点 2.2 B树的结构和节点组成 2.3 B树的插入 2.4 B树的删除操作 三、B树的优势和应用 3.1 B树在数据库系统中的应用 3.2 B树在文件系统中的应用 3.3 B树在内存管理中…

HTML5的多线程技术:Shared Worker的使用示例

Shared Worker 与普通的 Web Worker 类似&#xff0c;但不同之处在于它可以被多个浏览器窗口、标签页或者iframe共享&#xff0c;使得这些上下文之间能够相互通信。下面是一个使用 Shared Worker 的完整示例。共享Worker脚本&#xff08;sharedWorker.js&#xff09; self.add…

isupper()方法——判断字符串是否全由大写字母组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 isupper()方法用于判断字符串中所有的字母是否都是大写。isupper()方法的语法格式如下&#xff1a; str.isupper() 如果字符串中包含至少…

我是如何在bytemd中实现自定义目录的

介绍 接着上文说完&#xff0c;实现了在markdown编辑器中插入视频的能力&#xff0c;接下来还需要继续优化 markdown文档的阅读体验&#xff0c;比如 再加个目录 熟悉markdown语法的朋友可能会说&#xff0c;直接在编辑时添加 toc 标签&#xff0c;可以在文章顶部自动生成目录…

实验三 时序逻辑电路实验

仿真 链接&#xff1a;https://pan.baidu.com/s/1z9KFQANyNF5PvUPPYFQ9Ow 提取码&#xff1a;e3md 一、实验目的 1、通过实验&#xff0c;理解触发的概念&#xff0c;理解JK、D等常见触发器的功能&#xff1b; 2、通过实验&#xff0c;加深集成计数器功能的理解&#xff0c;掌…

⭐Ollama的本地安装⚡

先来逛一下咱们的主角Ollama的官网地址&#xff1a; Ollama 大概长这个样子&#x1f914; 因为本地系统的原因&#xff0c;文章只提供Widows的安装方式&#xff0c;使用Linux和Mac的大佬&#xff0c;可以自行摸索&#x1f9d0; 下载完成后就是安装了&#x1f355;&#xff0c…

一、Redis简介

一、Redis介绍与一般应用 1.1 基本了解 Redis全称Remote Dictionary Server(远程字典服务)&#xff0c; 是一个开源的高性能键值存储系统&#xff0c;通常用作数据库、缓存和消息代理。使用ANSI C语言编写遵守BSD协议&#xff0c;是一个高性能的Key-Value数据库提供了丰富的数…