← Назад к вопросам

Что хранил в ScriptableObject?

1.7 Middle🔥 111 комментариев
#C# и ООП

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое ScriptableObject и общие принципы его использования

ScriptableObject (SO) — это встроенный в Unity класс-контейнер данных, который не привязан к конкретному экземпляру игрового объекта (GameObject). Он существует как asset-файл в проекте, что позволяет хранить данные независимо от сцены. Его основная философия — разделение данных и логики. SO идеально подходит для информации, которая должна быть доступна из разных мест, не дублироваться в памяти и легко настраиваться в редакторе.

Что обычно хранят в ScriptableObject?

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

1. Конфигурационные данные и настройки (Data Containers)

Это самый распространенный случай. Вместо того чтобы "зашивать" значения в скрипты, мы выносим их в настраиваемые ассеты.

  • Параметры игрока/персонажа: Здоровье, скорость, сила прыжка, урон.
  • Настройки оружия: Урон, скорострельность, размер магазина, префаб снаряда.
  • Параметры врагов (противников): Здоровье, паттерны атаки, дроп лута, опыт за убийство.
  • Настройки игрового мира: Гравитация, настройки физики, громкость звуков по умолчанию.
// Пример: ScriptableObject для настроек персонажа
[CreateAssetMenu(fileName = "NewCharacterConfig", menuName = "Game/Character Config")]
public class CharacterConfig : ScriptableObject
{
    public float maxHealth = 100f;
    public float moveSpeed = 5f;
    public float jumpForce = 10f;
    public int baseDamage = 10;
    public AudioClip hitSound;
    public GameObject deathEffectPrefab;
}

2. Списки ссылок (Asset References)

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

  • Базы данных предметов (Item Database): Список всех доступных в игре мечей, зелий, ключей.
  • Пул звуков (Audio Libraries): Группировка звуковых клитов по категориям (интерфейс, выстрелы, музыка).
  • Списки врагов для волн (Wave Data): Состав волн в tower defence или шутере.
  • Наборы диалогов (Dialogue Containers): Все реплики для конкретного NPC или квестовой линии.
// Пример: База данных предметов
public class ItemDatabase : ScriptableObject
{
    public List<Item> allItems;

    public Item GetItemByID(string id)
    {
        return allItems.Find(item => item.itemID == id);
    }
}

3. Состояния и события (State & Events)

Использование SO для создания гибких систем взаимодействия, основанных на шаблоне "Наблюдатель" (Observer).

  • Каналы событий (Event Channels): GameEventSO с событием UnityEvent. Позволяет объектам подписываться и реагировать на события (например, "ИгрокНашелПредмет", "ВрагУмер"), не имея жестких ссылок друг на друга.
  • Переменные-ссылки (Variable References): FloatVariable, BoolVariable. Позволяют разным системам читать и записывать одно значение (например, текущее здоровье игрока), которое автоматически обновляется у всех "подписчиков".
  • Глобальные флаги игры (Game Flags): Отслеживание состояния квестов, открытых дверей, собранных предметов.
// Пример: Канал простого события
[CreateAssetMenu]
public class GameEventSO : ScriptableObject
{
    public UnityEvent OnEventRaised = new UnityEvent();

    public void RaiseEvent()
    {
        OnEventRaised?.Invoke();
    }
}

4. Сложные структуры данных

Для описания многоуровневых, иерархических данных.

  • Деревья диалогов (Dialogue Trees): Ветвящиеся диалоги с условиями, действиями и ссылками на следующие узлы.
  • Деревья навыков (Skill Trees): Описание зависимостей и улучшений способностей персонажа.
  • Рецепты крафта (Crafting Recipes): Список необходимых ингредиентов и результат.

Ключевые преимущества такого подхода

  • Отсутствие дублирования в памяти: Данные живут в одном месте в виде ассета, а не копируются в каждый MonoBehaviour.
  • Удобство настройки и итерации: Дизайнеры/художники могут менять баланс, не открывая код, через инспектор Unity.
  • Независимость от сцены: Данные доступны из любой сцены, что критично для менеджеров игры, экономики, сохранений.
  • Более чистая архитектура: Способствует соблюдению принципов SOLID, особенно Single Responsibility и Dependency Inversion.

Чего НЕ стоит хранить в ScriptableObject?

Важно понимать и ограничения. ScriptableObject не подходит для:

  • Динамических, часто меняющихся данных сессии (текущая позиция игрока, состояние конкретной двери). Для этого лучше подходят обычные классы или MonoBehaviour.
  • Хранения состояния сцены при переходе между сценами, если только это не часть системы сохранений, специально для этого спроектированной.
  • Прямой замены синглтонов (MonoBehaviour), управляющих сложной логикой в реальном времени. SO — это в первую очередь данные.

Таким образом, ScriptableObject — это мощный инструмент для создания модульной, удобной для дизайнеров и эффективной с точки зрения памяти архитектуры данных в проектах Unity.