Unity С# ждет

В настоящее время у меня есть этот код

void update()
{
    Debug.Log(1);
    StartCoroutine(wait());
    Debug.Log(4);
}
IEnumerator wait()
{
    Debug.Log(2)
    yield return new WaitForSeconds(3);
    Debug.Log(3)
}

Я хочу получить результат 1, 2, 3, 4, но вместо этого я получаю 1, 2, 4, 3. Я думаю, что могу неправильно понять, как здесь работают сопрограммы. Почему у меня такое поведение и как мне его исправить? заранее спасибо


person Nelson Yi    schedule 08.06.2017    source источник
comment
Вы можете вообще пропустить сопрограммы. Обычный стек функций будет вести себя так, как вы запрашиваете.   -  person Samy Bencherif    schedule 08.06.2017


Ответы (1)


Чтобы узнать больше о Coroutines, я рекомендую прочитать отличный ответ, данный здесь.

Чтобы дать высокоуровневую сводку для вашего кода, когда вы вызываете StartCoroutine для ожидания (), весь код до вашего оператора yield будет выполнен. Итак, теперь ваш вывод равен 1, 2. Когда вызывается yield, Unity вернет и выполнит код в update(), зарегистрировав int 4. Через 3 секунды он вернется к wait() и продолжит выполнение, давая окончательный вывод 1 ,2,4,3.

Если вы хотите вывести 1,2,3,4, вам нужно будет использовать yield return для вызова метода wait(), поэтому впоследствии будет напечатано 4. Для этого код в update() должен быть в самом методе возвращаемого типа IEnumerator.

void update()
{
    StartCoroutine(dosomething());
}

IEnumerator dosomething()
{
    Debug.Log(1);
    yield return wait();
    Debug.Log(4);
}

IEnumerator wait()
{
    Debug.Log(2);
    yield return new WaitForSeconds(3);
    Debug.Log(3);
}
person Steven Coull    schedule 08.06.2017
comment
Спасибо за ваше объяснение, но поскольку мне нужна моя функция ожидания для выполнения аналогичной задачи в нескольких разных разделах моей программы, есть ли способ разрешить эту последовательность выполнения без переноса кода в мою функцию ожидания? - person Nelson Yi; 08.06.2017
comment
Должна ли ваша функция ожидания вызываться в update(), которая не может быть типа IEnumerator? Чтобы приостановить процесс, записанный в настоящее время в update(), до тех пор, пока не завершится вызов wait(), этот код также должен находиться внутри сопрограммы. - person Steven Coull; 08.06.2017
comment
Не совсем, я просто не стал ждать, чтобы свалить туда код, потому что это выглядело бы неэффективно. Но если это единственный способ манипулировать последовательностью выполнения, то все будет хорошо. Спасибо за вашу помощь - person Nelson Yi; 08.06.2017
comment
В этом случае да, я бы создал другой метод, который возвращает IEnumerator, который (в вашем примере) печатает 1, запускает wait(), затем печатает 4 и запускает это в update(). Я обновил свой ответ выше, чтобы отразить это. - person Steven Coull; 08.06.2017