满足条件,但在协程

时间:2018-05-16 07:37:24

标签: c# unity3d

我有一个像这样的协程:

private IEnumerator ShortFlashes()
{
    this.startedShortFlashes = true;
    this.finishedShortFlashes = false;

    const int maxFlashes = 3;
    int numFlashesSoFar = 1;

    if (numFlashesSoFar > maxFlashes)
    {
        Debug.Log("All 3 short flashes finished!");
        this.finishedShortFlashes = true;
        yield break;
    }

    while (numFlashesSoFar <= maxFlashes)
    {
        yield return new WaitForSecondsRealtime(0.05f);
        this.Renderer.enabled = true;
        yield return new WaitForSecondsRealtime(0.05f);
        this.Renderer.enabled = false;

        Debug.Log("Number of short flashes so far: " + numFlashesSoFar);

        numFlashesSoFar++;
    }
}

当这个协程运行时,我可以在Unity控制台中看到消息,根据需要枚举短暂闪烁的次数。 (Debug.Log("Number of short flashes so far: " + numFlashesSoFar);)。

但是,Debug.Log("All 3 short flashes finished!");永远不会执行,即使numFlashesSoFar超过maxFlashes

这非常不方便,因为在我的Update()方法中,如果this.finishedShortFlashestrue,我还想执行一些其他操作。

如何解决此问题?

3 个答案:

答案 0 :(得分:4)

你已经对这些价值进行了硬编码。

const int maxFlashes = 3;
int numFlashesSoFar = 1;

if (numFlashesSoFar > maxFlashes)
{
    //...
}

if (numFlashesSoFar > maxFlashes)实际上等于if (1 > 3),这绝不是真的。

我真的不明白为什么你按照你的方式构建代码,这让我很难理解这里的核心问题。

这更有意义:

const int maxFlashes = 3;
int numFlashesSoFar = 1;

while (numFlashesSoFar <= maxFlashes)
{
    yield return new WaitForSecondsRealtime(0.05f);
    this.Renderer.enabled = true;
    yield return new WaitForSecondsRealtime(0.05f);
    this.Renderer.enabled = false;

    Debug.Log("Number of short flashes so far: " + numFlashesSoFar);

    numFlashesSoFar++;
}

Debug.Log("All 3 short flashes finished!");
this.finishedShortFlashes = true;

请注意,您不需要if。当while循环结束时,您已经知道条件已满足(否则while循环尚未完成。

我不了解代码中yield break;的用途。这似乎是不必要的,所以我删除了它。

答案 1 :(得分:0)

我认为你错过了yield关键字的重点。

执行遇到yield return后,执行将被转移回调用方法,并保留例程的执行状态。下次调用相同的例程时,执行将从其生成的位置继续执行。 有关详细信息,请参阅official documentation

在该特定情况下,行Debug.Log("All 3 short flashes finished!");永远不会被命中,因为当控件最初进入方法时,numFlashesSoFar变量设置为1,因此永远不会满足条件。然后它进入循环,遇到yield关键字。所以下一次,执行从循环内继续。

答案 2 :(得分:0)

我不明白为什么你把if语句放在循环之上。 while循环将继续,直到while语句为false。不需要if语句,你可以简单地将你的if-statement中的代码放在循环中:

private IEnumerator ShortFlashes()
{
    this.startedShortFlashes = true;
    this.finishedShortFlashes = false;

    const int maxFlashes = 3;
    int numFlashesSoFar = 1;

    while (numFlashesSoFar <= maxFlashes)
    {
        yield return new WaitForSecondsRealtime(0.05f);
        this.Renderer.enabled = true;
        yield return new WaitForSecondsRealtime(0.05f);
        this.Renderer.enabled = false;

        Debug.Log("Number of short flashes so far: " + numFlashesSoFar);

        numFlashesSoFar++; 
    }

    Debug.Log("All 3 short flashes finished!");
    this.finishedShortFlashes = true;
}

此外,您可以在Coroutine中看到yield return作为“代码中的临时中断”,因为它等待下一帧继续代码。除非你当然返回WaitForSeconds,否则它将等到给定的时间量过去。