Crowd Manager와 Avoidance
UCrowdManager, RVO 알고리즘, DetourCrowdAIController로 군중 회피 시스템을 구현합니다
UCrowdManager 개요
Detour Crowd 기반 군중 관리 시스템
UCrowdManager는 Detour Crowd 라이브러리를 기반으로 다수의 AI 에이전트가 서로 충돌하지 않으면서 이동하도록 관리합니다. 개별 경로 탐색 대신 군중 전체를 하나의 시스템으로 시뮬레이션합니다.
// CrowdManager 활성화
// Project Settings → Navigation System
// → Crowd Manager Class: CrowdManager (기본 설정)
// 또는 AIController에서 활성화
void AMyAIController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
// Crowd Following Component 사용
UCrowdFollowingComponent* CrowdComp =
Cast<UCrowdFollowingComponent>(
GetPathFollowingComponent());
if (CrowdComp)
{
// Crowd 시뮬레이션 활성화
CrowdComp->SetCrowdSimulationState(
ECrowdSimulationState::Enabled);
// Avoidance 품질 설정
CrowdComp->SetCrowdAvoidanceQuality(
ECrowdAvoidanceQuality::Medium);
// Avoidance Group (같은 그룹끼리 회피)
CrowdComp->SetAvoidanceGroup(1);
CrowdComp->SetGroupsToAvoid(1);
CrowdComp->SetGroupsToIgnore(0);
}
}
// CrowdManager 설정 (Project Settings)
// MaxAgents: 최대 관리 에이전트 수 (기본 50)
// MaxAgentRadius: 최대 에이전트 반지름
// MaxAvoidedAgents: 한 에이전트가 회피할 최대 수
// MaxAvoidedWalls: 회피할 최대 벽 수
// NavmeshCheckInterval: NavMesh 유효성 체크 간격CrowdManager는 전역 최적화를 수행합니다. 개별 에이전트가 독립적으로 회피하는 것보다, CrowdManager가 전체를 조율하면 좁은 통로에서의 데드락이나 진동 현상이 크게 줄어듭니다.
RVO(Reciprocal Velocity Obstacles) 알고리즘
속도 공간 기반 충돌 회피
RVO는 각 에이전트의 속도 공간에서 충돌을 회피하는 알고리즘입니다. 원하는 속도(목표 방향)와 충돌 회피 조건을 동시에 만족하는 최적 속도를 계산합니다.
// RVO Avoidance 원리
// 1. 각 에이전트의 원하는 속도(Preferred Velocity) 계산
// 2. 주변 에이전트의 속도 장애물(Velocity Obstacle) 계산
// 3. VO를 피하면서 Preferred에 가장 가까운 속도 선택
// 4. 양쪽 에이전트가 절반씩 양보 (Reciprocal)
// UE5 Avoidance 설정
// CharacterMovementComponent 기반:
UCharacterMovementComponent* MoveComp =
Character->GetCharacterMovement();
// RVO Avoidance 활성화
MoveComp->bUseRVOAvoidance = true;
MoveComp->AvoidanceConsiderationRadius = 500.f;
MoveComp->AvoidanceWeight = 0.5f; // 0~1 (회피 강도)
// Avoidance Group 설정
// 같은 그룹끼리만 회피
MoveComp->SetAvoidanceGroupMask(1); // 내 그룹
MoveComp->SetGroupsToAvoidMask(1); // 회피 대상 그룹
MoveComp->SetGroupsToIgnoreMask(0); // 무시 그룹
// Crowd vs RVO Avoidance 비교
// CharacterMovement RVO:
// - 간단한 설정
// - 에이전트 간 독립 계산
// - 소수의 AI에 적합
// - NavMesh 무관하게 동작
// Detour Crowd (CrowdManager):
// - NavMesh 기반 전역 최적화
// - 에이전트 간 상호 조율
// - 다수의 AI에 적합 (50+ 에이전트)
// - PathFollowing과 통합소수(10명 이하)의 AI는 CharacterMovement RVO가 설정이 간단하고, 대규모(50+) AI 군중은 Detour Crowd가 성능과 품질 면에서 우수합니다.
CrowdFollowingComponent 심화
군중 경로 추적의 세부 제어
UCrowdFollowingComponent는 UPathFollowingComponent를 상속하며, CrowdManager와 연동하여 군중 속에서의 경로 추적을 담당합니다.
// CrowdFollowingComponent 사용을 위한 AIController 설정
AMyAIController::AMyAIController(
const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass
<UCrowdFollowingComponent>(TEXT("PathFollowingComponent")))
{
// PathFollowingComponent를 CrowdFollowingComponent로 대체
}
// Avoidance Quality 레벨
enum class ECrowdAvoidanceQuality : uint8
{
Low, // 3 샘플 - 가장 빠름
Medium, // 6 샘플 - 적당
Good, // 12 샘플 - 좋음
High, // 20 샘플 - 최고 품질
};
// Separation 설정 (에이전트 간 최소 거리)
CrowdComp->SetCrowdSeparationWeight(2.0f);
// 높을수록 에이전트 간 거리 유지 강화
// Collision Avoidance 설정
CrowdComp->SetCrowdCollisionQueryRange(600.f);
// 충돌 검사 범위
CrowdComp->SetCrowdPathOptimizationRange(1000.f);
// 경로 최적화 범위 (코너 스무딩)
// Slow Down 설정
CrowdComp->SetCrowdSlowdownAtGoal(true);
// 목적지 근처에서 감속
// 시뮬레이션 상태 변경
// 상황에 따라 Crowd 사용 여부 전환
void AMyAIController::EnterCombat()
{
// 전투 시 Crowd 비활성 → 개별 이동
CrowdComp->SetCrowdSimulationState(
ECrowdSimulationState::ObstacleOnly);
// ObstacleOnly: 다른 에이전트를 장애물로만 취급
}
void AMyAIController::ExitCombat()
{
// 비전투 시 Crowd 복원
CrowdComp->SetCrowdSimulationState(
ECrowdSimulationState::Enabled);
}AIController 생성자에서 ObjectInitializer로 PathFollowingComponent를 대체해야 합니다. 런타임에 컴포넌트를 교체하는 것은 불가능하므로, 클래스 설계 시 미리 결정해야 합니다.
대규모 군중 최적화
수백 에이전트의 효율적 관리
수백 명의 AI를 동시에 관리하려면 LOD(Level of Detail) 전략과 분산 처리가 필수입니다. 거리에 따라 시뮬레이션 정밀도를 조절하는 패턴을 살펴봅니다.
// AI LOD 시스템
// 카메라/플레이어 거리에 따라 AI 품질 조절
UENUM()
enum class EAILODLevel : uint8
{
Full, // 전체 BT + Crowd + Animation
Reduced, // 간소화된 BT + Crowd, LOD 애니메이션
Minimal, // 단순 이동만, 회피 없음
Dormant, // 완전 정지 (Tick 비활성)
};
void AMyAIController::UpdateAILOD()
{
float DistToPlayer = GetDistToPlayer();
if (DistToPlayer < 2000.f)
{
SetAILOD(EAILODLevel::Full);
CrowdComp->SetCrowdAvoidanceQuality(
ECrowdAvoidanceQuality::High);
}
else if (DistToPlayer < 5000.f)
{
SetAILOD(EAILODLevel::Reduced);
CrowdComp->SetCrowdAvoidanceQuality(
ECrowdAvoidanceQuality::Low);
}
else if (DistToPlayer < 10000.f)
{
SetAILOD(EAILODLevel::Minimal);
CrowdComp->SetCrowdSimulationState(
ECrowdSimulationState::ObstacleOnly);
}
else
{
SetAILOD(EAILODLevel::Dormant);
// BT 일시 정지
if (BrainComponent)
BrainComponent->PauseLogic(TEXT("LOD Dormant"));
}
}
// Significance Manager 연동
// UE5의 Significance Manager가 자동으로
// 액터의 중요도를 계산하여 LOD 적용
// Project Settings → Significance Manager
// 활용: AI Tick 빈도, 애니메이션 LOD,
// Crowd Quality 자동 조절
// 분산 처리
// AI Tick을 여러 프레임에 분산
CrowdComp->SetCrowdSimulationState(
ECrowdSimulationState::Enabled);
// MaxSimulationTimestep: 프레임당 최대 시뮬 시간
// 초과 시 일부 에이전트는 다음 프레임에 처리Significance Manager를 활용하면 카메라 거리, 화면 점유율 등을 기준으로 자동 LOD가 적용됩니다. AI 수가 많은 게임에서는 필수적인 최적화 시스템입니다.
핵심 요약
- UCrowdManager는 Detour Crowd 기반으로 다수 에이전트의 이동을 전역 최적화한다
- RVO 알고리즘은 속도 공간에서 충돌 회피를 계산하며, CharacterMovement RVO와 Detour Crowd 두 가지 방식이 있다
- CrowdFollowingComponent는 ObjectInitializer로 생성 시 대체하며, Quality/Separation/SimulationState를 제어한다
- 대규모 군중은 AI LOD 시스템과 Significance Manager로 거리 기반 품질 조절이 필수이다
도전 과제
배운 내용을 직접 실습해보세요
CharacterMovementComponent의 bUseRVOAvoidance를 활성화하고 AvoidanceWeight를 설정하세요. 10개 이상의 AI를 좁은 통로에 배치하여 충돌 없이 이동하는지 확인합니다.
UCrowdManager의 MaxAgents와 MaxAvoidedAgents를 조절하며 성능을 측정하세요. DetourCrowdAIController를 사용하여 대규모 군중의 이동 품질과 CPU 비용을 비교합니다.
기본 RVO를 넘어 맥락 기반(Context-Based) 회피 시스템을 구현하세요. 전투 중인 AI는 회피 우선순위를 낮추고, 후퇴 중인 AI는 회피 우선순위를 높이는 등 상황별 가중치를 적용합니다.