Ответ 1
Перечислитель, созданный для вас, переименовывается. Один раз.
Компилятор будет генерировать класс, который реализует IEnumerator, который имеет функцию MoveNext() и свойство Current. Класс будет иметь все члены, необходимые для хранения состояния функции между вызовами. Точные детали можно рассматривать как "Compiler Magic".
Объект этого сгенерированного класса будет обрабатываться и управляться Unity3d Engine. Unity3d Engine будет вызывать MoveNext() для каждой активной сопрограммы после каждого кадра (если не указано иное).
Это позволило программисту Unity3d писать сценарии, которые воспроизводятся по одному кадру за раз. Комбинация магии компилятора С# и магии Unity3d Engine приводит к очень мощным, но простым в использовании скриптам.
Чтобы ответить на ваш вопрос: код в вашей функции будет выполнен один раз, но он будет приостановлен в инструкции return return.
Как указано выше, специальный компилятор, реализующий IEnumerator, создается компилятором С#.
При первом вызове MoveNext() ваша функция создает взрыв и устанавливает текущий объект в "новый WaitForSeconds (1.5f)".
Механизм Unity3d проверяет этот объект, видит, что он является экземпляром специального класса "WaitForSeconds", поэтому помещает перечислитель в очередь ожидания и не будет запрашивать второй элемент до 1,5 секунд. Тем временем будет отображаться много кадров и будет воспроизведен взрыв.
Через 1,5 секунды Unity выберет счетчик из очереди и снова вызовет MoveNext(). Вторая часть вашей функции будет выполняться сейчас, но не сможет создать второй объект. MoveNext() вернет false, чтобы указать, что ему не удалось получить новый элемент, который является сигналом Unity3d, чтобы выбросить этот счетчик. Сборщик мусора вернет память в определенный момент времени.
Как сказано: много компилятора и магия Unity3d продолжаются. До тех пор, пока вы помните, что ваша функция будет переведена на удержание до следующего кадра в каждом операторе возврата доходности, вы будете достаточно знать, чтобы воспользоваться этими специальными функциями.