Ошибка в системе восприятия врага — враги видят сквозь стены из-за отсутствия проверки Linecast. Или пустой NavMeshAgent, застрявший на стыке сцен. Такие баги убивают погружение и увеличивают время отладки на недели. Мы строим AI врагов на трёх слоях: сенсоры, принятие решений (Behaviour Tree или FSM) и память. Это исключает предсказуемость и даёт реалистичное поведение. Наша команда реализовала AI для 20+ проектов на Unity и Unreal, включая мобильные и ПК. Закажите разработку AI врагов — получите консультацию инженера.
Архитектура восприятия врага
Field of View (FOV) — стандартный метод: проверяем расстояние (до 20 единиц для среднего врага), угол (типично 90–120 градусов), и Linecast для прямой видимости. Если пропустить Linecast, враг будет реагировать на игрока за препятствием — баг, который часто встречается в инди-проектах.
Реализация Field of View
Field of View — конусная зона проверки. Не Physics.OverlapSphere сам по себе: сначала расстояние (Vector3.Distance < detectionRange), потом угол (Vector3.Angle(forward, dirToPlayer) < fovAngle / 2), потом Physics.Linecast для проверки линии видимости без препятствий. Без последнего враги видят сквозь стены.
Hearing — радиус без проверки угла, но с фильтром по типу звука. Шаги на металле слышны на 15 единиц, на мягком полу — на 5. Реализуется через AIPerceptionEvent публикуемый NoiseEmitter компонентами на движущихся объектах.
Last Known Position — критически важная концепция. Когда игрок исчезает из поля зрения, враг не «забывает» мгновенно. Хранится Vector3 lastKnownPosition и float lastSeenTime. В состоянии Investigation враг идёт к LKP, осматривается, только после таймаута (например, 5 секунд) переходит в Patrol.
Реализация пошагово
- Создайте компонент
AIPerceptionна враге. Добавьте публичные поляdetectionRange,fovAngle,hearingRadius. - В
Update()вызывайтеCheckVision()иCheckHearing(). - Для зрения:
Vector3.Distanceдо игрока, затемVector3.Angleдля угла, затемPhysics.Linecastот глаз врага до игрока. - Для слуха: подпишитесь на событие
AIPerceptionEventотNoiseEmitter. ИспользуйтеPhysics.OverlapSphereс фильтром по слою шумов. - Обновляйте
lastKnownPositionпри обнаружении. Если игрок потерян, запомните время. - Для группового алертинга: при обнаружении вызовите
Physics.OverlapSphereнаalertRadius(например, 30 единиц), найдите всех врагов с компонентомAIPerceptionи вызовите у нихReceiveAlert().
Behaviour Tree vs Finite State Machine: что выбрать?
FSM (Finite State Machine) — для простых врагов с 3–5 состояниями. Реализуется как enum EnemyState + switch в Update() или паттерн State с классами. Быстро пишется, легко дебажится. Проблема: при добавлении новых состояний количество переходов растёт квадратично и FSM превращается в «спагетти» уже при 8–10 состояниях.
Behaviour Tree (BT) — для сложных врагов. Behaviour Tree позволяет гибко моделировать поведение в 2–3 раза быстрее, чем FSM, при масштабировании до 10+ состояний. Дерево из Selector, Sequence и Leaf нод. Selector выполняет детей слева направо, останавливается на первом успешном. Sequence выполняет всех детей, останавливается на первом неуспешном. Leaf-ноды — атомарные действия (MoveToTarget, AttackPlayer, PlayAnimation) и условия (IsPlayerVisible, IsHealthLow).
Пример дерева для патрульного врага:
Selector ├── Sequence (атака) │ ├── IsPlayerInAttackRange │ └── AttackAction ├── Sequence (преследование) │ ├── IsPlayerVisible │ └── MoveToPlayerAction ├── Sequence (расследование) │ ├── HasLastKnownPosition │ └── MoveToLKPAction └── PatrolAction Популярные реализации BT для Unity: NodeCanvas, Behavior Designer, Unity Muse Behavior (официальный пакет). Кастомная реализация оправдана только для специфических нужд — готовые инструменты экономят недели.
| Характеристика | FSM | Behaviour Tree |
|---|---|---|
| Сложность расширения | Квадратичная | Линейная |
| Визуализация | Код, диаграммы | Визуальный редактор (обычно) |
| Повторное использование | Низкое | Высокое (поддеревья) |
| Подходит для | 3–5 состояний | 10+ состояний |
NavMesh: навигация и типичные проблемы
NavMeshAgent — компонент Unity для автоматической навигации по запечённому NavMesh. Базовое использование: agent.SetDestination(target). Но есть нюансы.
NavMeshAgent застревает на стыке двух NavMeshSurface — классическая проблема при аддитивной загрузке сцен. Каждая сцена имеет свою поверхность, соединения через NavMeshLink нужно настраивать явно. Компонент NavMeshSurface из пакета AI Navigation заменяет старый baked NavMesh и поддерживает рантайм-обновление для динамических препятствий через NavMeshObstacle. Подробнее в официальной документации Unity AI Navigation.
SetDestination каждый кадр — лишняя нагрузка. Пересчёт пути занимает несколько миллисекунд. Рекомендуется обновлять destination не чаще чем раз в 0.1–0.2 секунды через InvokeRepeating или проверку дистанции изменения позиции цели: если цель сдвинулась менее чем на 0.5f — пересчёт не нужен.
Stopping distance и arrive behavior. agent.stoppingDistance определяет дистанцию до цели, на которой агент останавливается. Для атакующего врага это attackRange - 0.5f. При изменении состояния (от Patrol к Chase) нужно менять stoppingDistance и speed — разные состояния требуют разных параметров агента.
Почему отладка AI через Gizmos критична?
AI отлаживается через Gizmos: нарисовать FOV-конус, LKP-точку, текущий путь агента, активное состояние над головой врага. Без визуализации в редакторе разобраться в поведении AI в рантайме практически невозможно.
Профилирование: NavMesh.pathfindingTimeSlice (время на путь за кадр), количество активных агентов. На мобильных платформах более 20 активных NavMeshAgent одновременно начинают заметно нагружать CPU. Решение — LOD для AI: на расстоянии враги переключаются на упрощённое поведение без пересчёта пути.
Память AI и групповое поведение
Простая память врага: AIMemory компонент с List<MemoryEntry> где каждый entry хранит position, type (player, sound, corpse), time. Старые записи удаляются по таймауту (например, 10 записей, каждая живёт 30 секунд). При принятии решений BT или FSM запрашивают память через GetMostRecentEntry(MemoryType.Player).
Алертинг группы — когда один враг обнаруживает игрока, он должен оповестить соседей. Реализуется через Physics.OverlapSphere на радиус alertRadius (30 единиц) с фильтром по тегу Enemy, вызов enemy.GetComponent<AIPerception>().ReceiveAlert(lastKnownPosition). Это децентрализованное решение не требует менеджера.
Flanking и coordination — для тактических AI. Одна из техник: NavMeshAgent.SamplePathPosition() используется для нахождения позиций на фланге игрока, враги распределяются по этим позициям через менеджер группы. Детали реализации зависят от жанра.
Грамотная реализация AI врагов сокращает время на отладку на 30–50%, что экономит бюджет тимлида в пересчёте на человеко-часы. Качественный AI позволяет сэкономить до $500 на ранней стадии разработки за счёт снижения числа итераций тестирования.
Что входит в работу?
- Анализ геймплейных требований и проектирование архитектуры AI
- Реализация систем восприятия (FOV, слух, LKP)
- Разработка поведенческих деревьев или конечных автоматов
- Настройка навигации (NavMesh, NavMeshLink, оптимизация)
- Интеграция памяти, алертинга и группового поведения
- Отладка через Gizmos, профилирование и оптимизация производительности
- Документация и обучение команды
- Сопровождение после деплоя
Ориентировочные сроки
| Сложность AI | Состав | Срок |
|---|---|---|
| Простой FSM | Patrol, Chase, Attack, 3 состояния | 3–5 дней |
| Средний | Perception, LKP, Investigation, Flee | 1–2 недели |
| Полный BT | NodeCanvas/Behavior Designer, группы, координация | 3–6 недель |
| Сложный тактический | Flanking, cover system, squad AI | 2–3 месяца |
Мы — команда с 10+ годами опыта в геймдеве, реализовали AI для 20+ проектов на Unity и Unreal. Гарантируем работоспособность и поддержим после сдачи. Свяжитесь с нами для консультации — мы подберём оптимальное решение для вашего проекта.






