Как понять эту единую сопрограмму?
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, возвращается выражение и текущее местоположение в коде сохраняется.