За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Разработка поведенческого ИИ для неигровых персонажей (NPC) в Unity часто начинается с простого и понятного шаблона: конечный автомат (FSM), реализованный через switch или if-else операторы над enum-перечислением состояний. Этот подход быстро становится препятствием по мере роста сложности проекта. Монолитный скрипт EnemyAI на тысячи строк, в котором перемешана логика патрулирования, атаки, реакция на звуки и обработка дебаффов, превращается в кошмар поддержки. Добавление нового поведения (например, эффекта "испуга") требует внесения хаотичных правок в десятки мест, нарушая принцип единственной ответственности (Single Responsibility Principle) и делая код хрупким.

В этой статье мы представим архитектурное решение, которое трансформирует разработку ИИ из задачи программирования в задачу конфигурации и композиции. Мы откажемся от управления состоянием через enum в пользу независимых, переиспользуемых ScriptableObject-ассетов для каждого поведения. Вы увидите, как:

Декомпозировать монолит на изолированные компоненты: PatrolStateSO, ChaseStateSO, AttackStateSO, EffectStateSO.

Интегрировать навигацию (NavMesh) и систему обнаружения игрока, не создавая жестких зависимостей.

Реализовать систему эффектов (оглушение, замедление), которая может как временно перехватывать контроль, так и модифицировать активное состояние.

Предоставить геймдизайнерам мощный и безопасный инструмент для настройки поведения врагов прямо в инспекторе Unity, без необходимости писать код.

Эта архитектура не просто решает проблему "спагетти-кода" — она создает экосистему для создания сложного, разнообразного и легко отлаживаемого ИИ, где новый тип поведения или эффект добавляется за минуты, а не за часы.

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Часть 1: Архитектурный фундамент — State Machine на Scriptable Objects

1.1 Почему мы отказались от классического FSM в коде

Традиционная реализация конечного автомата в Unity часто выглядит так:

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Проблемы такого подхода:

  1. Нарушение SRP (Single Responsibility Principle) — один класс отвечает за всё
  2. Сложность расширения — добавление нового состояния требует модификации существующего кода
  3. Плохая настраиваемость — параметры поведения захардкожены в скриптах
  4. Сложность отладки — логика всех состояний перемешана в одном месте

1.2 ScriptableObjects как идеальная абстракция для состояний

Мы выбрали ScriptableObjects по нескольким ключевым причинам:

Преимущества SO для FSM:

  1. Сепарация данных и логики
За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.
  1. Горячая перезагрузка (Hot Reload)
  2. Изменения параметров в инспекторе применяются моментально
  3. Не требует перекомпиляции или перезапуска игры
  4. Идеально для итеративного дизайна баланса
  5. Переиспользование и композиция
  6. Один PatrolStateSO может использоваться разными типами врагов. Параметры можно настраивать для каждого врага индивидуально
  7. Возможность создавать пресеты поведения
  8. Визуальное управление в инспекторе

1.3 Базовый класс AIStateSO: архитектура жизненного цикла

Рассмотрим ядро нашей системы — абстрактный класс AIStateSO:

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Ключевые особенности реализации:

  • Шаблонный метод (Template Method Pattern)
    1.1Базовый класс определяет структуру (OnEnter → OnUpdate → OnExit)
  • Производные классы переопределяют конкретные шаги
  • Инверсия зависимостей (Dependency Inversion)
За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.
  • Поддержка асинхронных операций
За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

1.4 Контекст AIEnemy: управление без микроменеджмента

Класс AIEnemy перестает быть "мозгом" врага и становится "диспетчером":

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Важные архитектурные решения:

  • Разделение шаблонов и экземпляров
За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.
  • Паттерн "Состояние" (State Pattern) в чистом виде
  • Контекст (AIEnemy) делегирует работу объекту состояния
  • Состояния могут заменять друг друга через контекст

1.5 Практический пример: создание нового состояния

Демонстрация расширяемости системы — добавляем FleeStateSO (состояние бегства):

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Результат: Мы добавили сложное поведение (тактическое отступление) без:

  1. Изменения существующего кода
  2. Модификации класса AIEnemy
  3. Риска сломать другие состояния

1.7 Выводы по архитектуре

Что мы получили:

  1. Чистая архитектура — каждый компонент решает одну задачу
  2. Невероятная гибкость — новые поведения добавляются за минуты
  3. Дизайнер-фриендли — настройка без программиста
  4. Легкость отладки — состояния изолированы, ошибки локализуются

Ключевые инсайты:

  • ScriptableObjects — это не только для данных, но и для поведения
  • Состояния должны быть глупыми — они получают все необходимое через параметры
  • Контекст должен быть минимальным — его задача только переключать состояния
  • Копирование SO обязательно — иначе состояние разделяется между врагами

Часть 3: Интеграция NavMesh — От хаотичного управления к системному подходу

В AIEnemyOLD.cs работа с NavMesh была распределена по всему коду без единой стратегии:

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.
За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

"Умный" код с побочными эффектами:

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Принципы проектирования навигации в новой системе

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Интеграция навигации с состояниями:

За пределами enum State: Создание масштабируемого, настраиваемого ИИ для врагов в Unity на основе Scriptable Objects.

Завершение

В рамках данной статьи мы представили модульную, расширяемую архитектуру искусственного интеллекта для врагов в Unity, построенную на основе конечного автомата с использованием ScriptableObjects. Эта система представляет собой не просто реализацию FSM, а продуманный фундамент для создания сложных поведенческих систем любого масштаба.

1
1 комментарий