Условие выполнено, но условное действие не выполнено в сопрограмме - PullRequest
0 голосов
/ 16 мая 2018

У меня есть сопрограмма, вот так:

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.finishedShortFlashes равен true.

Как я могу исправить эту проблему?

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

Я не понимаю, почему вы помещаете это выражение if над циклом.Цикл while будет продолжаться до тех пор, пока оператор while не станет ложным.Нет необходимости в операторе if, вы можете просто поместить код, который находится внутри вашего оператора if, ниже цикла:

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;
}

Кроме того, вы можете видеть yield return в сопрограмме в виде "временный перерыв в коде ", потому что он ожидает следующего кадра, чтобы продолжить код.Если, конечно, вы не вернете WaitForSeconds, он будет ждать, пока не пройдет указанное количество времени.

0 голосов
/ 16 мая 2018

Вы жестко закодировали значения.

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; в вашем кодеЭто кажется ненужным, поэтому я удалил его.

0 голосов
/ 16 мая 2018

Я думаю, вы упускаете точку ключевого слова yield.

Как только встреча с выполнением yield return, выполнение передается обратно в вызывающий метод, и состояние выполнения для подпрограммы сохраняется.В следующий раз, когда вы вызовете ту же самую процедуру, выполнение возобновится с того места, где оно было получено.Более подробная информация доступна в официальной документации

. В этом конкретном случае строка Debug.Log("All 3 short flashes finished!"); никогда не вводится, потому что, когда элемент управления изначально входит в метод, переменная numFlashesSoFarустановите в 1, чтобы условие никогда не выполнялось.Затем он входит в цикл, где встречается ключевое слово yield.Поэтому в следующий раз выполнение продолжается из цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...