Сделай по-своему
Урок 18 из 18 курса Игра в Unity: защита башен на Coddy.
В игре должна быть концовка. Игрок проигрывает, когда количество жизней достигает 0, и побеждает, когда отправлены все волны и на поле не осталось врагов. Спавнер знает, когда отправлена последняя волна, а Enemy.All знает, сколько врагов осталось, поэтому спавнер ждёт, пока поле опустеет, а затем вызывает событие, которое обрабатывает GameManager. Корутина ждёт выполнения условия с помощью WaitUntil, который проверяет лямбда-выражение один раз за кадр. Вот пример комнаты-головоломки, которая открывает выход, когда все переключатели включены:
yield return new WaitUntil(() => switchesOn == switches.Length);
exit.SetActive(true);При любом из вариантов завершения игры отображается EndPanel с сообщением, и игра останавливается с помощью Time.timeScale = 0. Количество жизней не опускается ниже 0: если Танк получает урон в 2 единицы, когда у него осталась 1 жизнь, значение сразу перескочит через 0, поэтому Mathf.Max не даёт ему стать меньше 0.
Кнопка «Играть снова» загружает сцену заново. Time.timeScale не является частью сцены и сохраняет своё значение после загрузки, поэтому остановленная на 0 игра запустилась бы снова замороженной: перед загрузкой верни значение 1.
Теперь настрой игру под себя. Все параметры баланса находятся в Inspector:
- GameManager игры:
startMoney(150) иstartLives(20). - Массив
wavesу спавнера: восемь строк с типом врага, количеством и интервалом между появлением врагов, а такжеtimeBetweenWaves(8). - Ресурсы EnemyData: скорость, здоровье, награда и количество жизней, которое отнимает каждый тип врага. У босса 450 единиц здоровья, и он отнимает 10 жизней.
- Ресурсы TowerData: стоимость, урон, дальность, скорострельность, значения улучшений, радиус поражения Cannon и замедление от Frost.
С настройками по умолчанию можно победить, построив смешанную оборону на поворотах пути и улучшая башни по мере поступления денег; несколько башен одного типа не удержат оборону. Меняй по одному параметру за раз и играй, чтобы понять, как он влияет на игру.
Задание
Сложно- В
WaveSpawnerдобавьpublic event Action AllWavesCleared. После отправки последней волны дождись, покаEnemy.Allопустеет, а затем вызови это событие. - В
GameManagerдобавь сериализованные поляendPanel(GameObject) иendText(TMP_Text). Число жизней никогда не опускается ниже 0, а когда оно достигает 0, игра заканчивается сообщениемGame Over. Когда все волны пройдены и остались жизни, игра заканчивается сообщениемYou Win!. При завершении показывается панель с сообщением, аTime.timeScaleустанавливается в 0. - Напиши
public void PlayAgain(), который вызывается кнопкой панели: верни нормальную скорость времени и заново загрузи активную сцену.
Нажми Play и защищай базу на протяжении всех восьми волн, затем нажми Check. После этого настрой игру в Inspector и играй по-своему.
Попробуйте сами
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
[SerializeField] private int startMoney = 100;
[SerializeField] private int startLives = 20;
[SerializeField] private WaveSpawner spawner;
[SerializeField] private TMP_Text moneyText;
[SerializeField] private TMP_Text livesText;
[SerializeField] private TMP_Text waveText;
private int money;
private int lives;
void OnEnable()
{
Enemy.ReachedBase += OnReachedBase;
Enemy.Killed += OnKilled;
spawner.WaveStarted += ShowWave;
}
void OnDisable()
{
Enemy.ReachedBase -= OnReachedBase;
Enemy.Killed -= OnKilled;
spawner.WaveStarted -= ShowWave;
}
void Start()
{
money = startMoney;
lives = startLives;
ShowMoney();
ShowLives();
}
public bool TrySpend(int amount)
{
if (amount > money)
{
return false;
}
money -= amount;
ShowMoney();
return true;
}
public void Earn(int amount)
{
money += amount;
ShowMoney();
}
void OnKilled(Enemy enemy)
{
Earn(enemy.data.reward);
}
void OnReachedBase(Enemy enemy)
{
lives -= enemy.data.damage;
ShowLives();
}
void ShowMoney()
{
moneyText.text = "Money: " + money;
}
void ShowLives()
{
livesText.text = "Lives: " + lives;
}
void ShowWave(int wave, int total)
{
waveText.text = "Wave " + wave + "/" + total;
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.