Как сделать переход между уровнями в Unity
Источник и полная интерактивная статья на сайте unitycraft.org:
Переход между уровнями в Unity 2D: настраиваем Build Settings, загружаем сцену через SceneManager и пишем готовый скрипт LevelLoader. Пошагово для новичка.
Как сделать переход между уровнями в Unity 2D
Первый уровень готов, играется — и почти сразу хочется большего: чтобы после финиша начинался следующий. И тут возникает логичный вопрос — а как вообще перекинуть игрока с одного уровня на другой? Спешу обрадовать: в Unity это делается буквально в пару строк. Каждый уровень здесь — это отдельная сцена (Scene), а переход между уровнями — просто её загрузка через класс SceneManager. Дальше мы пройдём весь путь по шагам: добавим уровни в сборку, напишем один универсальный скрипт LevelLoader под любую 2D-игру и повесим переход на финишную зону. Весь код готовый — копируй прямо к себе в проект.
Как устроен переход между уровнями в 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. Внутри — четыре готовых метода на все случаи жизни: следующий уровень, конкретный уровень по имени, перезапуск и выход в меню.
Скрипт можно найти в оригинальной статье:
Как использовать LevelLoader
Вся прелесть этого скрипта в том, что дёргать его методы можно откуда угодно:
- С кнопки в интерфейсе. Выдели UI-кнопку, в компоненте Button нажми «+» в блоке On Click, перетащи туда GameManager и выбери, скажем, LevelLoader.LoadNext или LevelLoader.Reload. Ноль строк кода — и кнопка работает.
- Из другого скрипта. Берёшь ссылку и вызываешь метод: FindFirstObjectByType<LevelLoader>().LoadNext(); (в новых версиях Unity это заменило устаревший FindObjectOfType; а ещё лучше — один раз закешировать ссылку в поле, а не искать объект каждый раз).
- Из триггера-финиша — как раз этим и займёмся на следующем шаге.
Лайфхак: метод LoadLevel(string) можно повесить прямо на кнопку и вписать имя сцены в поле параметра прямо в инспекторе. Так одна кнопка «Играть» отправит игрока в любой уровень — и всё это без единой правки в коде.
Шаг 3. Запускаем переход из финишной зоны
Скрипт у нас есть — осталось его чем-то запускать. В платформерах уровень чаще всего меняют в момент, когда игрок добегает до флажка, двери или портала. Давай сделаем такую невидимую финишную зону: пустой объект Finish с Box Collider 2D, у которого включена галочка Is Trigger. Такой коллайдер не толкает игрока и вообще ему не мешает — он просто ловит момент, когда тот вошёл внутрь.
Теперь вешаем на Finish совсем короткий скрипт. Как только в зону заходит игрок, он вежливо просит LevelLoader подгрузить следующий уровень:
Скрипт можно найти в оригинальной статье:
Совет: проверь на персонаже две вещи — что ему присвоен тег Player (список Tag вверху инспектора) и что на нём висят Rigidbody2D и Collider2D. Без них триггер будет молчать, а это ровно та мелочь, на поиск которой легко угробить полчаса.
Бонус: плавный переход с затемнением
Когда картинка меняется рывком, это немного бьёт по глазам. В играх посерьёзнее используют асинхронную загрузку SceneManager.LoadSceneAsync(): новая сцена тихо грузится в фоне, экран в это время плавно уходит в затемнение через CanvasGroup, а потом так же мягко проявляется. Для первых проектов это точно не обязательно — обычного LoadScene хватает за глаза, — но пусть этот приём полежит у тебя в копилке на будущее.
Частые ошибки перехода между уровнями
- Сцена не в списке сборки. Причина ошибки номер один, честное слово. Банально забыли добавить уровень в Build Profiles (в старых версиях — Build Settings).
- Опечатка в имени сцены. Для Unity LoadScene("level2") и "Level_2" — это два разных мира. Имя должно совпадать с файлом сцены буква в букву.
- Выход за границы списка. Вызвал buildIndex + 1 на последнем уровне без проверки — получил ошибку. У нас в LevelLoader эта проверка уже вшита, так что здесь ты подстрахован.
- Забыли Is Trigger или тег Player. Тогда финишная зона будет тихо стоять и делать вид, что её тут нет.
Вывод
Вот и всё — теперь у тебя в руках рабочая система перехода между уровнями: один LevelLoader на всю игру плюс лёгкая финишная зона, которую можно ставить хоть на каждый уровень. А дальше её легко достроить под себя: добавить экран «Уровень пройден», звук победы, сохранение прогресса или то самое плавное затемнение. Если же Unity для тебя пока тёмный лес и хочется начать с самых азов — с установки, первого проекта и первого скрипта — загляни на бесплатный курс Unity Старт от UnityCraft.org, а потом посмотри и полную программу обучения. Удачи с игрой!