Данная статья будет полезна начинающим разработчикам игр. В ней я расскажу о собственном опыте реализации мультисценного взаимодействия и проблемах с которыми я столкнулась.
Поговорим о статических классах для хранения данных, различных способах подгрузки сцен движком Unity, а также коснёмся кейса подключения Admob к проекту. Информация предоставлена официальной документацией и доброжелательным коммьюнити разработчиков.
Ситуация
Моя игра представляет собой две сцены — главное меню, которое видно сразу при загрузке и, непосредственно, игровая сцена с механикой, в которую в зависимости от выбранной опции подгружается префаб объекта. Объединить их в одну сцену мне не представлялось возможным, так как на меню завязано несколько довольно сложных объектов, да и удобнее всё же разделять сущности.
Ранее для хранения данных я бы просто использовала некий объект-контроллер, но с выгрузкой сцены он перестаёт существовать.
Передача данных (static class)
Оказалось, что Unity превосходно умеет работать с кодом, даже если он мирно лежит файликом в папке скриптов и не прикреплён компонентом к объекту на сцене (это было не очевидно для новичка). Например, таким файлом может быть статический класс такого вида:
using UnityEngine;
public static class DataHolder
{
private static GameObject prefabName;
public static GameObject Prefab
{
get
{
return prefabName;
}
set
{
prefabName = value;
}
}
}
Таким образом, мне удалось сохранить выбор пользователя даже после выгрузки сцены и загрузки новой. Изначально всё работало именно с жёстким переключением сцен.
С помощью такого механизма можно также передавать в другие сцены настройки из меню, например — язык локализации, настройки звуков и музыки и многое другое.
Мультисценность (SceneManagement)
Меня всё устраивало и так, пока не поступила задача подключить к проекту Admob (рекламу), таким образом, чтобы ролик показывался прямо в начале игровой сцены. Как выяснилось, тут есть тонкости: запрос ролика занимает существенное время, и он просто не успевает прийти при переключении сцен. Лепить дополнительные задержки в проекте не хотелось, тем более, что у нас есть куча времени, пока игрок «залипает» в меню. Тут я и узнала, что переключать сцены «жёстко» нет никакой необходимости, ведь есть замечательная опция аддитивной загрузки (без выгрузки предыдущей сцены).
Подгружаю игровую сцену контроллером меню (сцена с меню и объектом рекламы остаётся загруженной тоже):
SceneManager.LoadScene(1,LoadSceneMode.Additive);
По завершению уровня, выгружаю сцену игры игровым контроллером (чтобы не висела в памяти):
SceneManager.LoadScene(0,LoadSceneMode.Single);
С использованием такой схемы, реклама загружается сразу при старте приложения, и вызвать показ рекламного ролика можно в любой нужный момент. Аналогично можно поступать с любыми необходимыми вам объектами.
Проблемы
К сожалению, даже при аддитивной загрузке сцен, не удастся вволю покопаться в объектах одной сцены из другой. Ссылки на объекты придётся передавать через некий «медиатор» (в моём случае использовался тот самый статический класс).
Будьте внимательны при инстанцировании префабов, если активны несколько сцен — у меня они все решили затолкаться в неправильную сцену (об этом в другой раз).
Автор: apocatastas