Помилка в системі сприйняття ворога — вороги бачать крізь стіни через відсутність перевірки 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 та arrivial 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. Гарантуємо працездатність і підтримаємо після здачі. Зв'яжіться з нами для консультації — ми підберемо оптимальне рішення для вашого проєкту.






