Как эта функция с «доходом» подробно работает?

StackOverflow https://stackoverflow.com/questions/3438670

Вопрос

Я получил этот метод (внутри скрипта Unity C #), но я не понимаю, как работает часть «доходности».

Я знаю из MSDN, что функция вернет IEnumerator, который я мог бы повторить, но этот код ждет 1,5 секунды и не требует итерации, потому что это будет означать, что объекты, созданные внутри, были созданы несколько раз. Любой здесь, кто может объяснить мне, как работает этот код?

IEnumerator DestroyShip()
{
    // create new gameobject
    Instantiate(ExplosionPrefab, transform.position, transform.rotation);
    // make current gameobject invisible
    gameObject.renderer.enabled = false;
    // set new position for the current gameobject
    transform.position = new Vector3(0f, transform.position.y, transform.position.z);
    // wait for 1,5 seconds 
    yield return new WaitForSeconds(1.5f);
    // make the current gameobject visible again
    gameObject.renderer.enabled = true;
}
Это было полезно?

Решение

Перечисление компилятор генерирует для вас, итерации. Один раз.

Компилятор будет генерировать класс, который реализует IEnumerator, который имеет функцию MOVENEXT () и текущее свойство. Класс будет иметь все участники, необходимые для хранения состояния функции между вызовами. Точные детали можно считать «магией компилятора».

Объект этого сгенерированного класса будет обрабатываться и управляться двигателем Unity3D. Двигатель Unity3D позвонит MOVENEXT () на каждом активном Corotine после каждого кадра (если не указано иное).

Это позволило программисту Unity3D, чтобы написать сценарии, которые разыгрывают один кадр за раз. Сочетание магии C # Compiler Magic и Enity3D Engine Magic приводит к очень мощным, но легко использованным сценариям.

Чтобы ответить на ваш вопрос: код в вашей функции будет выполнен один раз, но он будет паузой в операторе «Доходность возврата».

Как указано выше, специальный объект, который реализует IEnumerator, создается компилятором C #.

При первом вызове TO MOVENEXT () ваша функция создает взрыв и устанавливает текущий объект на «Новые quitForseconds (1.5f)».

Enity3D Engine проверяет этот объект, видит, что это экземпляр специального класса «WaitForseconds», поэтому помещает перечислетель на некоторую очередь ожидания и не попросит второй элемент до тех пор, пока не пройдено 1,5 сек. Тем временем многие рамки будут оказаны, и взрыв будет воспроизведен.

После 1,5 с, Unity будет ворчать перечислитель из очереди и снова вызовите movenext (). Вторая часть вашей функции будет выполняться сейчас, но не будет сгенерировать второй объект. MOVENEXT () вернет false, чтобы указать, что он не сможет получить новый элемент, который является сигналом для Unity3D, чтобы бросить этот перечислитель. Коллектор мусора будет восстанавливает память в какой-то момент времени.

Как сказано: много компилятора и Unity3D Magic происходит. До тех пор, пока вы помните, что ваша функция будет введена в удержание до следующего кадра при каждом операторе возврата дохода, вы найдете достаточно, чтобы извлечь выгоду из этих специальных функций.

Другие советы

Если yield Используется один раз, так как будто вы возвращали IEnumerator с одним элементом, поэтому вы получаете впечатление, что он не является итерацией.

Это довольно странное использование ключевого слова доходности, трудно понять, почему он был реализован так, не увидев весь контекст.

Лучше вернуться IEnumerable скорее, чем IEnumerator Поскольку оно больше льстимых и простых в использовании. Еще лучше использовать IEnumerable<T>. Отказ Возвращение доходности - это просто синтаксический сахар для реализации блока итератора, компилятор генерирует актуальный код, поскольку он является по сути стандартной пластиной котельной, которая может быть легко сгенерирована. Как правило, вы обычно используете доходность, когда вы хотите сделать серию единых действий Apear, чтобы быть коллекцией, например:

public IEnumerable<Thing> GetThings()
{
    yield return GetNextThing();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top