Удаление объекта при проигрыше
При проигрыше будем удалять объект CubePlace. Добавим проверку стабильности башни, используя компонент Rigidbody, вне метода Update.
if (allCubes.GetComponent<Rigidbody>().velocity.magnitude > 0.1f)
{
// Башня падает
}
Проверяем модуль вектора скорости (velocity). Значение > 0.1f указывает на движение объекта, и, следовательно, падение башни. В этом случае удаляем CubePlace:
Destroy(cubePlace);
Для предотвращения многократного срабатывания кода при падении башни, используем булеву переменную:
bool isFallen = false;
Модифицируем код:
if (!isFallen && allCubes.GetComponent<Rigidbody>().velocity.magnitude > 0.1f)
{
Destroy(cubePlace);
isFallen = true;
}
Теперь CubePlace удаляется единожды.
Обработка ошибок после удаления объекта
После удаления CubePlace возможны ошибки, связанные с обращением к несуществующему объекту. Добавим условие:
if (!isFallen && allCubes != null && allCubes.GetComponent<Rigidbody>().velocity.magnitude > 0.1f)
{
Destroy(cubePlace);
isFallen = true;
}
Это предотвращает обращение к cubePlace после его удаления.
Метод SpawnPosition, работающий с cubePlace, также может вызвать ошибки. Хотя проверка cubePlace != null предотвращает вызов SpawnPosition после удаления cubePlace, запущенная с помощью StartCoroutine корутина продолжает работу. Для её остановки используем переменную:
Coroutine spawnCoroutine;
Запускаем и сохраняем корутину:
spawnCoroutine = StartCoroutine(SpawnPosition());
Останавливаем корутину при проигрыше:
if (!isFallen && allCubes != null && allCubes.GetComponent<Rigidbody>().velocity.magnitude > 0.1f)
{
StopCoroutine(spawnCoroutine);
Destroy(cubePlace);
isFallen = true;
}
Пользовательский интерфейс проигрыша
Используем Canvas. Прикрепим его к основной камере (Main Camera), установив расстояние до камеры 1 и Render Mode на Screen Space — Overlay. Это обеспечит масштабирование элементов UI вместе с экраном.
Создадим папку Sprites и добавим туда изображение для кнопки перезапуска (можно использовать собственное или создать в Figma). Установим Max Size спрайта в 256. Добавим кнопку (Button) на Canvas, удалим её текст и назначим созданный спрайт. Настроим Aspect Ratio для сохранения пропорций и Anchors для корректного отображения на экранах разных размеров.
Скрипт перезапуска игры
Создадим C# скрипт (RestartButton.cs), содержащий функцию RestartGame():
using UnityEngine;
using UnityEngine.SceneManagement;
public class RestartButton : MonoBehaviour
{
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
Скрипт использует SceneManager для перезагрузки текущей сцены. Добавим скрипт на кнопку, назначим функцию RestartGame() на событие On Click. Кнопка будет неактивна по умолчанию и активируется при проигрыше. Добавим эффект нажатия, изменив цвет кнопки. Также отодвинем камеру при проигрыше, изменив её Z-координату.
public GameObject restartButton;
...
restartButton.SetActive(true);
// Отодвинуть камеру
Camera.main.transform.Translate(Vector3.forward * -3);
Теперь при проигрыше появляется кнопка «Перезапуск», перезапускающая игру при нажатии.
В этом уроке реализована система проигрыша, включающая удаление объектов, обработку ошибок и пользовательский интерфейс с кнопкой перезапуска. Система обеспечивает корректное поведение игры при проигрыше.