Как понять эту единую сопрограмму?

using UnityEngine;
using System.Collections;

public class CoroutineExample : MonoBehaviour
{
    IEnumerator Start ()
    {
        print ("Starting " + Time.time);
        yield return StartCoroutine (WaitAndPrint ());
        print ("Done " + Time.time);
    }

    IEnumerator WaitAndPrint ()
    {
        yield return new WaitForSeconds (5f);
        print ("WaitAndPrint " + Time.time);
    }
}

Результат

Starting 0
WaitAndPrint 5.010554
Done 5.010554

У меня есть два вопроса?

Во-первых, как понять возвращаемое значение функции Start (). Раньше я видел, что возвращаемое значение Start () является недействительным. И, на мой взгляд, Start () выполняется Unity только один раз (один кадр), но возвращение yield возвращает функцию Start () в два кадра;

Во-вторых, я также смущен результатом. Я думаю, что результат должен быть

Starting 0
Done 5.010554
WaitAndPrint 5.010554

Потому что StartCoroutine () запускает функцию WaitAndPrint(). В функции WaitAndPrint() yield return заставляет эту функцию приостанавливаться в этом кадре и возвращаться к Start (). Затем Start () продолжает работу и печатает "Done xxxxx". Через 5 секунд WaitAndPrint() возобновляет работу и печатает "WaitAndPrint xxxxx".

Где я не прав?

4 ответа

Решение

Когда вы звоните yield return контроль взят Unity.

Когда вы начинаете Coroutine Единство возьмет IEnumerator возвращается методом и будет вызывать MoveNext на IEnumerator вернулся.

На основе типа объекта и значений в объекте Unity решит, что делать.

В твоем случае в Start метод yield заявление вернуть другое IEnumerator так единство не позову MoveNext на Start возвращаемый объект до второго IEnumerator отделки.

В WaitAndPrint первый MoveNext возвращает WaitForSeconds объект, на основе которого Unity решает, что не будет вызывать MoveNext в течение 5 секунд. Через 5 секунд он звонит MoveNext снова и остальная часть метода выполняется, который является только этой строкой

print ("WaitAndPrint" + Time.time);

Как IEnumerator вернулся yield return StartCoroutine (WaitAndPrint ()); подошел к концу, он будет называть MoveNext на IEnumerator который был возвращен Start это, в свою очередь, выполнит то, что когда-либо осталось от Start:

print ("Done " + Time.time);

Надеюсь, это достаточно ясно:)

Вот как я понимаю этот результат:

Функция Start() вызывается Unity один раз и печатает "Запущено".

Затем следующая строка делает две вещи:

yield return StartCoroutine (WaitAndPrint ());
  • он запускает сопрограмму WaitAndPrint()
  • он ожидает его завершения, прежде чем продолжить в сопрограмме Start().

Подпрограмма WaitAndPrint() сделает свое дело:

  • Подождите 5 секунд
  • Распечатать "WaitAndPrint" + время

Затем сопрограмма Start() возобновит работу и напечатает "Done" + время.

Вот почему

print ("WaitAndPrint" + Time.time);

печатается раньше:

print ("Done " + Time.time);

Также вам следует отредактировать свой пост, в первом результате он пропускает пробел:

WaitAndPrint5.010554

Должно быть

WaitAndPrint 5.010554

Извините, если неясно, я впервые отвечаю на Stackru, надеюсь, это помогло!

Вместо IEnumerators вы можете "почти" всегда использовать метод Invoke. Попробуйте поработать с этим, и ваша жизнь станет проще:)

IEnumerators являются блоками итераторов, они не обязательно выполняются в течение 1 кадра, когда вы yield returnВы, по сути, говорите, что нужно перебирать несколько кадров.

Когда в методе итератора достигается оператор yield return, возвращается выражение и текущее местоположение в коде сохраняется.

Другие вопросы по тегам