为什么不是我的“收益率”?工作

本文关键字:收益率 工作 我的 为什么不 | 更新日期: 2023-09-27 18:02:26

我是一个编程新手,我感觉这里有一个非常愚蠢的错误。但是谁能解释我,为什么不是4条消息之间的延迟2秒,我立即得到最后一条消息只显示。

using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using UnityEngine.UI;
public class Wait : MonoBehaviour {
    private int i = 0;
    public string[] message;
    [SerializeField]
    private Text toText;
    public IEnumerator Message(float waitTime)
    {
        toText.text = message[i];
        i++;
        yield return new WaitForSeconds(waitTime = 2f);
    }
    void Start()
    {
        StartCoroutine(Message(i));
        StartCoroutine(Message(i));
        StartCoroutine(Message(i));
        StartCoroutine(Message(i));
    }
}

为什么不是我的“收益率”?工作

void Start()
{
    StartCoroutine(Message(i));
    StartCoroutine(Message(i));
    StartCoroutine(Message(i));
    StartCoroutine(Message(i));
}

我不认为那是在做你认为应该做的事。这将不会等待每个StartCoroutine完成,并将调用下一个StartCoroutine

结果如下:

第一次调用StartCoroutine(Message(i));将启动Message功能。一旦遇到yield return new WaitForSeconds(waitTime = 2f);行代码,它就会跳转回Start()函数。

下一个StartCoroutine(Message(i));将被调用,然后同样的事情将再次发生。

当从非协程函数调用协程函数时,只要您有yield return new WaitForSeconds, yield return null;yield return(无论YieldInstruction是什么实现的),执行将返回到调用StartCoroutine函数的非协程函数并继续执行其他代码。

要使协程等待另一个协程完成,则从另一个协程函数调用StartCoroutine(Message(i));函数。这将允许您yield每个协程函数调用。这被称为链接协同程序。

要链接或yield一个协程函数调用,只需将yield return放在StartCoroutine函数前面。yield return StartCoroutine(Message(i));

public class Wait : MonoBehaviour {
    private int i = 0;
    public string[] message;
    [SerializeField]
    private Text toText;
    public IEnumerator Message(float waitTime)
    {
        // toText.text = message[i];
        i++;
        yield return new WaitForSeconds(waitTime = 2f);
    }
    void Start()
    {
        StartCoroutine(startMessage());
    }
    IEnumerator startMessage()
    {
        yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
        yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
        yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
        yield return StartCoroutine(Message(i));//Wait until this coroutine function retuns
    }
}

现在,每个StartCoroutine(Message(i));调用将等待直到第一个调用完成。您总是可以使用boolean变量来做到这一点,但最好是将StartCoroutine调用yield

立即设置文本的原因是StartCoroutine将执行Message的枚举器。

发生的前两件事是设置文本和增加i。只有在这之后,你才能得到WaitForSeconds。此时,StartCoroutine将暂停Message的进一步执行。

如果你在yield return之后有一行,你会在2秒后看到它的效果。

在文档中的示例

中,您还可以看到yield return Wait之后的行为https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html

我建议运行下一个测试,以更加熟悉yield return的工作方式:

IEnumerator MessageOuter() {
    Console.WriteLine("outer 1");
    var inner = MessageInner();
    Console.WriteLine("outer 2");
    return inner;
}
IEnumerator MessageInner() {
    Console.WriteLine("inner 1");
    yield return new WaitForSeconds(1);
    Console.WriteLine("inner 2");
    yield return new WaitForSeconds(1);
    Console.WriteLine("inner 3");
}
void Start() {
    Console.WriteLine("start 1");
    var outer = MessageOuter();
    Console.WriteLine("start 2");
    StartCoroutine(outer);
    Console.WriteLine("start 3");
}