Как использовать ScriptableObject и упростить себе жизнь

15343

Как использовать ScriptableObject и упростить себе жизнь

Любой движок предоставляет пользователю набор инструментов для работы. Движок во многом упрощает жизнь разработчикам, однако лишь в том случае, если разработчик правильно использует эти инструменты.

В Unity существует самый известный базовый класс — MonoBehaviour и большая часть скриптов наследует от него.Этот класс содержит все методы, необходимые для работы в Unity. Например  Start(), Update(), Instantiate(), GetComponent() и множество других.

MonoBehaviour- скрипты обязаны прикрепляться к объектам. Они существуют в префабах и сцене. Содержат функции, которые реагируют на события Unity: Awake(), Update(), OnTriggerEnter() и другие. Применение этих скриптов вполне понятно: “объект, сделай что-нибудь, когда получишь сигнал”.

Существует также класс ScriptableObject, применение которого не так очевидно и требует пояснений.

Как использовать ScriptableObject
Как использовать ScriptableObject

У ScriptableObject есть свои особенности:

  1. Они не находятся в сцене — не изменяются при переключении режима игры.
  2. Имеют мало callback-ов — OnEnable(), OnDisable(), OnDestroy().
  3. Хранятся как .asset файлы.

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

Самое важное отличие ScriptableObject от MonoBehaviour это то, как они проходят сериализацию.

Что такое сериализация

Если коротко, то сериализация — это способ записи данных для хранения: на диск или в файл. Процесс сериализации — это кодировка данных в последовательность байтов для последующего сохранения или передачи в память, на диск или просто файл. Данные, сохраненные таким образом позже можно воссоздать, например в процессе выполнения программы. Такой процесс имеет название — десериализация. Сам объект сериализуется в поток, который, помимо данных, содержит еще и информацию о самом объекте — версия, тип объекта, язык, имя сборки и тд.

Существует тонна способов проводить сериализацию объектов

В Unity есть свой способ сериализации объектов и данных. Например сохранение файлов в текст, json и тд.

Сериализация в Unity

Когда мы запускаем или отключаем режим игры (play-mode) или изменяем какой-нибудь скрипт в Unity, все сборки с .dll-ками проекта должны быть перезагружены. Тут и происходит процесс сериализации\десериализации.

Это значит, что все изменения сделанные в режиме игры не будут сохранены при выходе из него. И во время работы в Unity это важно помнить — наверняка многие совершали такую ошибку: отредактировать сцену, выставить все на свои места,а потом выйти из play mode и все потерять.

Поля в классах, наследуемых от MonoBehaviour, сериализуются просто как значения. Поэтому, при десериализации может произойти следующее: ссылка на объект пропадает, но создается копия этого объекта. Подобное приводит к потере связей между объектами.

ScriptableObjects во время сериализации

Ссылки на ScriptableObjects сохраняются как ссылки (references) а значит взаимодействия между объектами сохраняются при сериализации\десериализации и данные не повторяются.

Очень важно знать что SO не находятся в сцене и поэтому они не проходят процесс сериализации\десериализации во время запуска play-mode или перезагрузки сборок. И это самое важное, так как изменения, сделанные в SO во время работы play-mode будут сохраняться при выходе из него! Что значительно упрощает жизнь во время разработки и открывает новые возможности.

Используем ScriptableObject для хранения данных

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

Конечно, можно создать пустой префаб в котором хранить эти данные, но это не то, для чего существуют префабы.Мало того, подобное легко приводит к ошибкам, которые тяжело исправлять.

Достичь нужного результата можно с помощью ScriptableObject. Создается SO в котором есть нужные поля. Что бы создавать объекты SO через инспектор обозначаем класс как [CreateAssetMenu] и у в Asset-Create появляется пункт с названием нашего SO.

Код выглядит примерно так:

CreateAssetMenu
CreateAssetMenu

Теперь этот SO можно создать как обычный объект — материал или спрайт через Create — [Имя класса]. 

Это теперь —  шаблон по которому будут создаваться все враги в игре. А для каждого экземпляра можно настраивать свои параметры.

Что бы присвоить игровому объекту созданные значения нужно создать ссылку на SO в MonoBehaviour-скрипте. И всё — мы получили отличную систему хранения данных, которая не удаляется при перезапусках игры, значения не сбрасываются, а сам файлик хранится как .asset — один файл-один объект и к тому же легко управляем.

Тем, кто хочет перейти от создания прототипов и маленьких проектов к чему-то более серьезному и масштабному следует обратить внимание на SciptableObjects — они могут значительно упростить жизнь и в разы ускорить разработку игры.

Всем остальным так же будет полезно обратить на них внимание — никогда не рано упростить себе жизнь. А если хотите изучать работу в Unity или  продвинуться в освоении движка, существует хороший сайт https://unity3dschool.ru, где вы найдете уроки по разным темам. На сайте можно найти и то, что полезно новичкам, и то что интересно для более продвинутых пользователей. Заходите — знакомьтесь.