Первый уровень готов, играется — и почти сразу хочется большего: чтобы после финиша начинался следующий. И тут возникает логичный вопрос — а как вообще перекинуть игрока с одного уровня на другой? Спешу обрадовать: в Unity это делается буквально в пару строк. Каждый уровень здесь — это отдельная сцена (Scene), а переход между уровнями — просто её загрузка через класс SceneManager. Дальше мы пройдём весь путь по шагам: добавим уровни в сборку, напишем один универсальный скрипт LevelLoader под любую игру и повесим переход на финишную зону. Весь код готовый — копируй прямо к себе в проект.
Как устроен переход между уровнями в Unity
Смотри: в Unity вообще нет отдельной штуки под названием «уровень» — вместо неё работает сцена. Меню — это сцена, первый уровень — сцена, второй — ещё одна. Поэтому «сменить уровень» на деле означает загрузить нужную сцену: старая закрывается, новая открывается. Всю работу берёт на себя метод SceneManager.LoadScene(), а обратиться к сцене можно двумя способами:
- По индексу — это порядковый номер сцены в списке сцен сборки (счёт идёт с нуля). Отлично подходит для «дай мне следующий уровень по порядку».
- По имени — это просто строка с названием файла сцены, например
"Level_2". Пригодится, когда нужен конкретный уровень или возврат в меню.
Оба варианта рабочие — и, чтобы не пришлось выбирать, ниже мы соберём скрипт, где есть сразу и тот, и другой.
Шаг 1. Добавляем уровни в сборку (Build Profiles)
Здесь есть момент, о который спотыкаются почти все новички: Unity не сможет загрузить сцену, пока ты не добавишь её в сборку. Открой File → Build Profiles (так это меню называется в Unity 6; в версиях постарше — File → Build Settings) и добавь все уровни в список Scene List в том порядке, в котором игрок будет их проходить. Рядом сразу появятся их индексы — 0, 1, 2 и дальше по списку.
Частая ошибка: если сцены нет в списке сцен сборки, при загрузке Unity просто выдаст ошибку. Если что-то не работает — первым делом загляни в Build Profiles и убедись, что уровень в списке и стоит на своём месте.
Шаг 2. Универсальный скрипт LevelLoader
Можно, конечно, прописывать загрузку сцены в каждом объекте по отдельности — но такой проект быстро превращается в кашу. Куда спокойнее живётся с одним скриптом-менеджером. Создай C#-скрипт LevelLoader и повесь его на пустой объект GameManager. Внутри — четыре готовых метода на все случаи жизни: следующий уровень, конкретный уровень по имени, перезапуск и выход в меню.
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelLoader : MonoBehaviour
{
// Следующий уровень по порядку из списка сборки
public void LoadNext()
{
int next = SceneManager.GetActiveScene().buildIndex + 1;
if (next < SceneManager.sceneCountInBuildSettings)
SceneManager.LoadScene(next);
else
SceneManager.LoadScene(0); // уровни кончились — на первый
}
// Конкретный уровень по имени сцены
public void LoadLevel(string sceneName)
{
SceneManager.LoadScene(sceneName);
}
// Перезапустить текущий уровень (например, после проигрыша)
public void Reload()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
// Вернуться в меню — первую сцену в списке
public void LoadMenu()
{
SceneManager.LoadScene(0);
}
}
Как использовать LevelLoader
Вся прелесть этого скрипта в том, что дёргать его методы можно откуда угодно:
- С кнопки в интерфейсе. Выдели UI-кнопку, в компоненте
Buttonнажми «+» в блоке On Click, перетащи тудаGameManagerи выбери, скажем,LevelLoader.LoadNextилиLevelLoader.Reload. Ноль строк кода — и кнопка работает. - Из другого скрипта. Берёшь ссылку и вызываешь метод:
FindFirstObjectByType<LevelLoader>().LoadNext();(в новых версиях Unity это заменило устаревшийFindObjectOfType; а ещё лучше — один раз закешировать ссылку в поле, а не искать объект каждый раз). - Из триггера-финиша — как раз этим и займёмся на следующем шаге.
Лайфхак: метод LoadLevel(string) можно повесить прямо на кнопку и вписать имя сцены в поле параметра прямо в инспекторе. Так одна кнопка «Играть» отправит игрока в любой уровень — и всё это без единой правки в коде.
Шаг 3. Запускаем переход из финишной зоны
Скрипт у нас уже есть — осталось только чем-то его запускать. В платформерах уровень чаще всего меняется в тот момент, когда игрок добегает до флажка, двери или портала. Давайте сделаем такую невидимую финишную зону: создайте пустой объект Finish с компонентом Box Collider 2D (если у вас 2D-проект) или Box Collider (если проект 3D) и включите у него галочку Is Trigger. Такой коллайдер не отталкивает игрока и никак не мешает его движению — он просто определяет момент, когда игрок входит в эту зону.
Теперь вешаем на Finish совсем короткий скрипт. Как только в зону заходит игрок, он вежливо просит LevelLoader подгрузить следующий уровень:
using UnityEngine;
public class FinishZone : MonoBehaviour
{
[SerializeField] private LevelLoader loader; // Перетащите сюда объект с компонентом LevelLoader
// Для 2D-проекта оставьте этот метод, а OnTriggerEnter() удалите.
private void OnTriggerEnter2D(Collider2D other)
{
// Реагируем только на игрока
if (!other.CompareTag("Player"))
return;
loader.LoadNext();
}
// Для 3D-проекта оставьте этот метод, а OnTriggerEnter2D() удалите.
private void OnTriggerEnter(Collider other)
{
// Реагируем только на игрока
if (!other.CompareTag("Player"))
return;
loader.LoadNext();
}
}
Совет: проверьте две вещи: что персонажу присвоен тег Player (поле Tag в верхней части инспектора) и что на нём есть Rigidbody2D и Collider2D (для 2D-проекта) или Rigidbody и Collider (для 3D-проекта). Без этих компонентов событие триггера не сработает, а поиск такой мелочи легко может отнять полчаса.
Бонус: плавный переход с затемнением
Когда картинка меняется рывком, это немного бьёт по глазам. В играх посерьёзнее используют асинхронную загрузку SceneManager.LoadSceneAsync(): новая сцена тихо грузится в фоне, экран в это время плавно уходит в затемнение через CanvasGroup, а потом так же мягко проявляется. Для первых проектов это точно не обязательно — обычного LoadScene хватает за глаза, — но пусть этот приём полежит у тебя в копилке на будущее.
Частые ошибки перехода между уровнями
- Сцена не в списке сборки. Причина ошибки номер один, честное слово. Банально забыли добавить уровень в Build Profiles (в старых версиях — Build Settings).
- Опечатка в имени сцены. Для Unity
LoadScene("level2")и"Level_2"— это два разных мира. Имя должно совпадать с файлом сцены буква в букву. - Выход за границы списка. Вызвал
buildIndex + 1на последнем уровне без проверки — получил ошибку. У нас вLevelLoaderэта проверка уже вшита, так что здесь ты подстрахован. - Забыли Is Trigger или тег Player. Тогда финишная зона будет тихо стоять и делать вид, что её тут нет.
Вывод
Вот и всё — теперь у тебя в руках рабочая система перехода между уровнями: один LevelLoader на всю игру плюс лёгкая финишная зона, которую можно ставить хоть на каждый уровень. А дальше её легко достроить под себя: добавить экран «Уровень пройден», звук победы, сохранение прогресса или то самое плавное затемнение. Если же Unity для тебя пока тёмный лес и хочется начать с самых азов — с установки, первого проекта и первого скрипта — загляни на бесплатный курс Unity Старт, а потом посмотри и полную программу обучения. Удачи с игрой!