Menu
CoddyTech

Обратный отсчёт

Урок 23 из 25 курса Игра на Unity: Tower Defense на Coddy.

Между волнами игрок строит, а обратный отсчёт показывает, сколько времени осталось. Готовый игрок может вызвать следующую волну раньше времени с помощью кнопки. Перерыв — это цикл в корутине, который возвращает null, поэтому он выполняется один раз за кадр: отсчитывает время, показывает его и завершается, когда время истекает или когда кнопка запрашивает волну. Кнопка только устанавливает логическое значение, а цикл считывает его:

while (left > 0f && !skipRequested)
{
    // покажи оставшиеся секунды, веди обратный отсчёт, подожди один кадр
}
skipRequested = false;

После использования логическое значение снова становится false, иначе каждый перерыв после первого завершался бы сразу. Mathf.CeilToInt округляет вверх, поэтому при оставшихся 2.3 секундах отображается 3. yield return StartCoroutine(Countdown()); запускает обратный отсчёт и ждёт его завершения.

challenge icon

Задание

Сложно

Выполняй обратный отсчёт перед каждой волной; кнопка запускает её раньше.

  1. В WaveSpawner добавь сериализованные countdownText (TMP_Text) и nextWaveButton (GameObject), private bool callNow; и public void CallNextWave() { callNow = true; }.
  2. Замени break на yield return StartCoroutine(Countdown());: покажи кнопку и, пока остаётся время и callNow не равно true, показывай Next wave in 8, округляя значение вверх, в каждом кадре.
  3. Затем снова установи callNow в false, очисти текст и скрой кнопку.

Нажми «Играть»: кнопка «Следующая волна» пропускает ожидание. Затем нажми «Проверить».

Попробуйте сами

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WaveSpawner : MonoBehaviour
{
    [SerializeField] private List<Wave> waves = new List<Wave>();
    [SerializeField] private Transform[] waypoints;
    [SerializeField] private float timeBetweenWaves = 8f;

    void Start()
    {
        StartCoroutine(RunWaves());
    }

    IEnumerator RunWaves()
    {
        for (int i = 0; i < waves.Count; i++)
        {
            yield return new WaitForSeconds(timeBetweenWaves);
            Debug.Log("Wave " + (i + 1));
            Wave wave = waves[i];
            for (int n = 0; n < wave.count; n++)
            {
                Enemy enemy = Instantiate(wave.enemy, waypoints[0].position, Quaternion.identity);
                enemy.waypoints = waypoints;
                yield return new WaitForSeconds(wave.spacing);
            }
        }
        Debug.Log("All waves sent");
    }
}

Все уроки раздела Игра на Unity: Tower Defense

Потренируйтесь самостоятельно: Песочница Unity