📜  Unity协程

📅  最后修改于: 2021-01-11 13:52:13             🧑  作者: Mango

Unity协程

协程是允许暂停执行并在满足条件后从同一点恢复的函数。可以说,协程是一种特殊的函数,用于统一执行,以停止执行直到满足某些特定条件并从中断的地方继续执行。

这是C#函数和Coroutines函数之间除语法之外的主要区别。典型的函数可以返回任何类型,而协程必须返回IEnumerator,并且在返回之前必须使用yield。

可以使用协程有两个原因:异步代码和需要在多个框架上进行计算的代码。

因此,基本上,协程可以使我们将工作分解为多个框架,您可能以为我们可以使用Update函数来做到这一点。您是正确的,但我们对Update函数没有任何控制权。协程代码可以按需或以不同的频率执行(例如,每5秒而不是每帧)。

IEnumerator MyCoroutineMethod() {
   // Your code here...
   
   yield return null;
}

例:

IEnumerator MyCoroutine()
{
  Debug.Log("Hello world");
  yield return null; 
//yield must be used before any return
}

在这里,yield是一个特殊的return语句。它告诉Unity暂停脚本并在下一帧继续。

我们可以以不同的方式使用yield:

yield return null-在下一帧调用All Update函数后,将恢复执行。

yield return new WaitForSeconds(t)-在(大约)t秒后恢复执行。

yield return new WaitForEndOfFrame()-渲染所有相机和GUI后恢复执行。

yield return new WaitForFixedUpdate()-在所有脚本上调用所有FixedUpdates之后恢复执行。

yield return new WWW(url) -URL的Web资源被下载或失败后,它将恢复执行。

启动协程

我们可以通过两种方式启动协程:

基于字符串:

句法:

StartCoroutine( string functionName)

例:

StartCoroutine("myCoroutine")

基于IEnumerator的:

句法:

StartCoroutine(IEnumerator e)

例:

StartCoroutine(myCoroutine())

停止协程

我们可以使用相同的方式来停止协程。在这里,我们将使用StopCoroutine而不是调用StartCoroutine:

基于字符串:

句法:

StopCoroutine( string functionName)

例:

StopCoroutine("myCoroutine")

基于IEnumerator的:

句法:

StopCoroutine(IEnumerator e)

例:

StopCoroutine(myCoroutine())

例子1

让我们看一个简单的示例,了解协程的工作原理。为此,创建一个圆形精灵。然后创建一个脚本文件,将其命名为ColorChanger.cs并复制以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorChanger : MonoBehaviour
{
    
private SpriteRenderer sr;

public Color color1;
public Color color2;

void Start () {
   sr = GetComponent();
   StartCoroutine(ChangeColor());
}

 IEnumerator ChangeColor() {
   
   while (true) {
      
      if (sr.color == color1)
         sr.color = color2;
      
      else
         sr.color = color1;
      
      yield return new WaitForSeconds(3);
   }
}
}

将此脚本文件附加到Sprite的组件上。并在color1和color2变量中选择两种颜色。

现在,当您玩此游戏时,我们的圆圈对象将以3秒的间隔在两种颜色之间切换。

输出:

例子2

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TimeChange : MonoBehaviour
{
    IEnumerator WaitAndPrint()
    {
        // suspend execution for 5 seconds
        yield return new WaitForSeconds(5);
        print("WaitAndPrint " + Time.time);
    }

    IEnumerator Start()
    {
        print("Starting " + Time.time);

        // Start function WaitAndPrint as a coroutine
        yield return StartCoroutine("WaitAndPrint");
        print("Done " + Time.time);
    }
}

输出: