Unity中协程IEnumerator的使用详细介绍

Unity中协程IEnumerator的使用详细介绍

在Unity中,通用方法是顺序执行的,通用方法也是一帧执行的。当我们写的方法需要一定的时间时,帧率会下降,画面也会下降。卡顿现象。当我们调用一个方法让一个对象慢慢消失时,除了在Update中进行相关操作,Unity还提供了一个更方便的方法,那就是协程。

一般情况下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调用的时机。在进行比较复杂的计算时,如果没有严格的时间顺序unity 多次执行协程,我们可以每帧执行一个循环来完成计算,或者每帧执行指定的计算。防止程序运行时出现卡顿现象的循环次数。

收益率介绍:

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()后不会等待协程内容返回,会立即执行后续代码。

虽然协程非常方便灵活,但使用不当会给程序带来不可预知的后果。使用前请慎重考虑。

这是Unity中协程IEnumerator使用的详细介绍。更多Unity协程IEnumerator相关内容,请搜索往期文章或继续浏览下方相关文章。我希望你以后会享受更多。支持!