Unity中协程IEnumerator的使用方法介绍详解
作者:做一只会飞的猪 发布时间:2023-03-31 13:28:44
在Unity中,一般的方法都是顺序执行的,一般的方法也都是在一帧中执行完毕的,当我们所写的方法需要耗费一定时间时,便会出现帧率下降,画面卡顿的现象。当我们调用一个方法想要让一个物体缓慢消失时,除了在Update中执行相关操作外,Unity还提供了更加便利的方法,这便是协程。
在通常情况下,如果我们想要让一个物体逐渐消失,我们希望方法可以一次调用便可在程序后续执行中实现我们想要的效果。
我们希望代码可以写成如下所示:
void Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
}
}
然而该方法在调用时将在一帧中执行完毕,无法实现预期的效果。如果将该方法改写并放到Update函数中可实现我们预期的效果,但是还不够优雅。
float time = 0f;
float fadeTime = 2f;
void Fade()
{
time += Time.dealttime;
Color c = renderer.material.color;
c.a = 1f - time/fadeTime;
renderer.material.color = c;
}
Unity中的协程方法通过yield这个特殊的属性可以在任何位置、任意时刻暂停。也可以在指定的时间或事件后继续执行,而不影响上一次执行的就结果,提供了极大地便利性和实用性。
协程在每次执行时都会新建一个(伪)新线程来执行,而不会影响主线程的执行情况。
正如上边的方法,我们使用协程可以更加方便的实现我们想要的效果。
void Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield return null;//下一帧继续执行for循环
yield return new WaitForSeconds(0.1f);//0.1秒后继续执行for循环
}
}
我们通过StartCoroutine()函数来调用协程函数。
值得注意的是,协程并不会在Unity中开辟新的线程来执行,其执行仍然发生在主线程中。当我们有较为耗时的操作时,可以将该操作分散到几帧或者几秒内完成,而不用在一帧内等这个操作完成后再执行其他操作。
如我们需要执行一个循环:
IEnumerator CaculateResult()
{
for (int i = 0; i < 10000; i++)
{
//内部循环计算
//在这里的yield会让改内部循环计算每帧执行一次,而不会等待10000次循环结束后再跳出
//yield return null;
}
//如果取消内部的yield操作,仅在for循环外边写yield操作,则会执行完10000次循环后再结束,相当于直接调用了一个函数,而非协程。
//yield return null;
}
调用协程的方法有两种,分别是StartCoroutine(/这里直接调用方法,添加参数/),另一种是StartCoroutine(/这里填写”字符串的方法名字”,方法参数/)。第一种方法的优势在于可以调用多个参数的方法,后一种方法只能调用不含参数或只包含一个参数的协程方法。但是第一种方法不能通过StopCoroutine(/这里填写”字符串的方法名”/)来结束协程,只能通过StopAllCoroutines来结束。后一种则可以通过StopCoroutine来结束对正在执行的协程的调用。
协程在实现过程中我们需要注意yield调用的时机,执行较为复杂的计算时,如果在时间上没有严格的先后顺序,我们可以每帧执行一次循环来完成计算,或者每帧执行指定次数的循环来防止在程序运行中出现的卡顿现象。
yield return的介绍:
yield return null; // 下一帧再执行后续代码
yield return 0; //下一帧再执行后续代码
yield return 6;//(任意数字) 下一帧再执行后续代码
yield break; //直接结束该协程的后续操作
yield return asyncOperation;//等异步操作结束后再执行后续代码
yield return StartCoroution(/*某个协程*/);//等待某个协程执行完毕后再执行后续代码
yield return WWW();//等待WWW操作完成后再执行后续代码
yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行
yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响);
yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响);
yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码
yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候....如:yield return new WaitUntil(() => frame >= 10);
yield return new WaitWhile()//将协同执行直到 当输入的参数(或者委托)为false的时候.... 如:yield return new WaitWhile(() => frame < 10);
当某一个脚本中的协程在执行过程中,如果我们将该脚本的enable设置为false,协程不会停止。只有将挂载该脚本的物体设置为SetActive(false)时才会停止。
Unity在调用StartCoroutine()后不会等待协程中的内容返回,会立即执行后续代码。
虽然协程十分方便和灵活,但不当的使用会使程序产生无法预想的后果,请使用前慎重考虑。
来源:https://blog.csdn.net/beihuanlihe130/article/details/76098844


猜你喜欢
- 目前很多软件安装时都会出现引导页面,用户体验很好。下面就来DIY下:因为视频上传很麻烦,所以截图了。首先看看效果图:点击小点可自由切换,滑动
- Pattern类定义public final class Pattern extends Object implementsSerializ
- 本文介绍了idea 创建 maven web 工程流程(图文教程),分享给大家,具体如下:1创建一个project工作区间;2.创建一个ma
- JAVA虽然是在C++基础上发展而来,但却对C++的许多缺陷有所改进,其中一个不得不提的就是字符串,我们知道,随着学习的深入,进入MFC时,
- 有时间我们在使用多线程的时候,需要取消线程的执行,可以使用CancellationTokenSource来取消对Task开辟多线程的取消如下
- HttpServletRequest介绍HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HT
- SpringBoot线程池和Java线程池的用法和实现原理使用默认的线程池方式一:通过@Async注解调用public class Asyn
- Java 的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程的执行。join 线程Thread 提供了让一个线程等
- 举个例子Map < String , Object > jsonMap = new HashMap< String , O
- 1. web.xml中配置了CharacterEncodingFilter,配置这个是拦截所有的资源并设置好编号格式。encoding设置成
- 本文实例为大家分享了java使用集合实现通讯录的具体代码,供大家参考,具体内容如下代码有些繁琐,只适合初学者。项目1java通讯录方法(声明
- 一、引言大家都知道单例模式,通过一个全局变量来避免重复创建对象而产生的消耗,若系统存在大量的相似对象时,又该如何处理?参照单例模式,可通过对
- 本文实例为大家分享了C++实现图书馆管理系统的具体代码,供大家参考,具体内容如下总体思想用C++开发图书馆管理系统需要对学生和图书分别建立c
- 堆排序是一种树形选择排序方法,它的特点是:在排序的过程中,将array[0,...,n-1]看成是一颗完全二叉树的顺序存储结构,利用完全二叉
- 本篇开始介绍Jetpack Compose 中的修饰符Modifier。修饰符可以用来执行以下操作:更改可组合项的大小、布局、行为和外观。添
- 我们在做微服务时,有时候需要将微服务做一些限制,比如只能我们自己的服务调用,不能通过浏览器直接调用等。我们可以使用spring cloud
- 本文以一个C#的SQL数据库字串操作函数为例,说明如何实现对SQL字符串过滤、检测SQL是否有危险字符、修正sql语句中的转义字符,确保SQ
- 如何使用 Jetpack Compose 创建翻转卡片效果介绍在电子商务和银行应用程序中输入卡信息是很常见的情况。我认为让用户更轻松地处理这
- Shiro提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再
- 前言现在一般很少有用Android原生app发送邮件的需求,但是前段时间公司项目需要在Android app 内部发送邮件,于是就在网上收集