Как стать автором
Обновить

Передача данных между сценами в Unity — применение мультисценности в разработке простых игр

C# *Unity *Дизайн игр *
Из песочницы
Данная статья будет полезна начинающим разработчикам игр. В ней я расскажу о собственном опыте реализации мультисценного взаимодействия и проблемах с которыми я столкнулась.

Поговорим о статических классах для хранения данных, различных способах подгрузки сцен движком 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);

С использованием такой схемы, реклама загружается сразу при старте приложения, и вызвать показ рекламного ролика можно в любой нужный момент. Аналогично можно поступать с любыми необходимыми вам объектами.

Проблемы


К сожалению, даже при аддитивной загрузке сцен, не удастся вволю покопаться в объектах одной сцены из другой. Ссылки на объекты придётся передавать через некий «медиатор» (в моём случае использовался тот самый статический класс).

Будьте внимательны при инстанцировании префабов, если активны несколько сцен — у меня они все решили затолкаться в неправильную сцену (об этом в другой раз).

Ссылки на документацию
Теги:
Хабы:
Всего голосов 34: ↑29 и ↓5 +24
Просмотры 30K
Комментарии Комментарии 23