AI-система поведения NPC на основе RL
RL для NPC (Non-Player Characters) заменяет конечные автоматы (FSM) и Behaviour Trees там, где требуется адаптивность. Противники в шутерах, союзники в RPG, пешеходы в GTA-style играх — RL агенты ведут себя непредсказуемо и интересно, адаптируются к стилю игрока.
Почему RL для NPC
FSM/BT ограничения:
- Разработчик вручную описывает каждый переход
- Edge cases → "тупые" NPC (застревание у стены, очевидные паттерны)
- Масштабирование: добавление нового поведения = переписывание дерева
RL преимущества:
- NPC учится на опыте взаимодействия с игроком
- Адаптируется к нестандартным тактикам
- Единый framework для разных типов поведения
Unity ML-Agents
Стандартный стек для игровых NPC:
// C# компонент агента в Unity
public class NPCCombatAgent : Agent
{
public override void CollectObservations(VectorSensor sensor)
{
// позиция и скорость игрока (relative)
sensor.AddObservation(RelativePlayerPosition);
sensor.AddObservation(PlayerVelocity);
// собственное состояние
sensor.AddObservation(Health / MaxHealth);
sensor.AddObservation(Ammo / MaxAmmo);
sensor.AddObservation(IsInCover);
// environment
sensor.AddObservation(NearestCoverDistance);
}
public override void OnActionReceived(ActionBuffers actions)
{
float moveX = actions.ContinuousActions[0];
float moveZ = actions.ContinuousActions[1];
bool shoot = actions.DiscreteActions[0] == 1;
bool takeCover = actions.DiscreteActions[1] == 1;
// применяем действия к персонажу
MoveNPC(moveX, moveZ);
if (shoot) Shoot();
if (takeCover) SeekCover();
}
public override void OnEpisodeBegin()
{
ResetPosition();
Health = MaxHealth;
}
}
Reward для боевого NPC:
void FixedUpdate()
{
if (DamagedPlayer()) AddReward(1.0f);
if (TookDamage()) AddReward(-0.5f);
if (Killed()) AddReward(-10.0f);
if (KilledPlayer()) AddReward(10.0f);
AddReward(-0.001f); // time penalty — не стоять
}
Self-Play для боевых NPC
Проблема: против какого игрока обучать NPC? Против random агента — научится только базовому. Решение: Self-Play.
# ML-Agents training config с self-play
behaviors:
NPC:
trainer_type: ppo
self_play:
save_steps: 50000
team_change: 100000
swap_steps: 2000
play_against_latest_model_ratio: 0.5
window: 10
NPC обучается против предыдущих версий себя → постоянное улучшение, нет reward hacking против конкретной стратегии.
Observation Design
Ray Perception: лучевые сенсоры для восприятия окружения (как sonar/radar). До 20 лучей, видит теги объектов + расстояние.
// в Unity ML-Agents: добавить RayPerceptionSensor3D компонент
// DetectableTags: ["Player", "Cover", "Wall", "Enemy"]
// RaysPerDirection: 5, SphereCastRadius: 0.5
Camera Sensor: CNN обрабатывает render texture. Медленнее ray perception, но более реалистичная "зрительная система".
Behaviour Trees + RL гибрид
Чистый RL для NPC в production — редкость (непредсказуемость неприемлема для гейм-дизайнеров). Гибрид:
BehaviourTree:
→ Selector:
→ IsPlayerVisible AND HealthHigh → RL AggressivePolicy
→ IsPlayerVisible AND HealthLow → RL RetreatPolicy
→ PatrolTask (детерминированный)
RL policy для конкретных фаз боя + BT для high-level structure. Дизайнеры контролируют структуру, RL заполняет детали.
Типы поведений для обучения
Тактические:
- Фланкирование (обход сзади)
- Использование укрытий
- Подавляющий огонь / прикрытие союзников
- Retreat / retreat and heal
Социальные (для NPC-жителей):
- Реакция на игрока (страх, любопытство, агрессия)
- Социальные группы, диалоги-реакции
- Адаптация к репутации игрока
Экономические (для торговцев):
- Ценообразование на основе спроса
- Принятие предложений о торговле
Scalable Training
Обучение тысяч NPC параллельно:
# в Python: параллельные среды Unity
from mlagents_envs.environment import UnityEnvironment
from mlagents_envs.envs.unity_parallel_env import UnityParallelEnv
env = UnityParallelEnv(UnityEnvironment("game.x86_64"))
# Unity запускает N агентов одновременно
# каждый environment step = obs/actions для всех N
GPU training через ONNX: После обучения через ML-Agents → экспорт в ONNX → Barracuda runtime прямо в Unity. Инференс на GPU без Python.
Сроки: 8–20 недель
Базовый боевой NPC с self-play — 6 недель. Полноценная система с несколькими типами поведений, BT+RL гибридом, production-ready inference — 14–20 недель.







