AI 에이전트 몬스터 어그로 분산과 유저 둘러싸기 협동 패턴 설계 가이드
AI 에이전트 몬스터가 한 유저에게 겹치거나 전투가 단조로워지는 문제를 줄이기 위한 설계안을 정리한다. 위협도 분산, 역할 배정, 슬롯 기반 Surrounding, 재평가 규칙을 조합하고 실제 공정성과 가독성은 플레이테스트로 확인한다.

핵심 요약
모든 AI 개체가 가장 높은 위협도의 유저를 바로 목표로 삼으면 같은 유저 주변에 몰릴 수 있다. 한 가지 설계안은 개체별 목표 점수, 파티 단위 역할 배정, 목표 주변 슬롯 예약을 분리하는 것이다. 이 구조가 어그로 분산이나 대응 시간을 개선하는지는 게임의 이동·공격 규칙과 플레이테스트로 확인해야 한다.
왜 몬스터 어그로가 한 유저에게 쏠리는가?
단순한 타깃 선정 규칙의 한 예는 가장 큰 Threat를 가진 유저를 공격한다이다. 이 규칙에서는 모든 몬스터가 같은 Threat 표와 후보 조건을 사용하면 목표가 한 유저에게 몰릴 수 있다.
- 모든 근접 몬스터가 같은 좌표를 목표로 이동하면 충돌하거나 겹칠 수 있다.
- 탱커 역할이 없는 게임에서는 한 명에게 피해가 집중될 수 있다.
- 원거리 몬스터까지 같은 유저만 조준하도록 설계하면 전투 공간의 변화가 줄 수 있다.
- 행동 신호나 위치 규칙이 없다면 유저가 포위 위험을 미리 읽기 어려울 수 있다.
따라서 Threat를 타깃 후보를 좁히는 신호로 쓰고, 거리·현재 공격자 수·역할·이동 비용도 점수에 반영하는 방식을 실험할 수 있다. 어느 방식이 더 안정적인지는 게임별 테스트로 판단한다.
어그로 분산 점수는 어떻게 설계할까?
각 몬스터가 유저 p를 선택할 때 쓸 수 있는 예시 점수식이다. 항목마다 단위와 범위가 다르므로, 가중치를 정하기 전에 입력값을 비교 가능한 범위로 정규화하고 실제 게임에서 조정한다.
| 기호 | 의미 | 설계 의도 |
|---|---|---|
T(p) | 유저의 누적 위협도 | 피해량, 회복량, 도발, 목표물 방해 등을 게임 규칙에 맞춰 반영 |
D(m,p) | 몬스터와 유저의 이동 거리 | 먼 타깃으로의 불필요한 군집 이동 방지 |
F(p) | 현재 해당 유저를 공격 중인 몬스터 수 | 집중 공격을 줄이고 싶을 때 시험할 항 |
R(m,p) | 역할 부적합 비용 | 예: 측면 기습병이 정면 슬롯을 고르는 경우의 패널티 |
S(p) | 최근 집중 피해 또는 무력 상태 보정 | 급격한 집중 공격을 완화하려는 설계 항 |
Threat는 이벤트 기반으로 갱신한다
아래는 이벤트 때 위협도를 더하고 시간에 따라 감소시키는 간단한 예시다. 피해·회복·도발을 어떤 크기로 반영할지와 감소를 적용할지는 게임 규칙에 따라 정한다.
// Illustrative example: call on the game's owning thread, with active-player entries initialized.
// Call AddThreat with non-negative event values; choose the cap and decay policy for the game.
public void AddThreat(Player player, float amount)
{
threat[player.Id] = Mathf.Min(threat[player.Id] + amount, threatCap);
}
public void DecayThreat(float deltaTime)
{
foreach (var id in threat.Keys.ToArray())
threat[id] = Mathf.Max(0f, threat[id] - threatDecayPerSecond * deltaTime);
}
DecayThreat 예시를 그대로 컴파일하려면 파일에 using System.Linq;가 필요하다. ThreatTable은 활성 플레이어의 항목을 먼저 초기화한다고 가정한다. 샘플은 단순화를 위해 호출 스레드와 컬렉션 동기화를 다루지 않으므로, 병렬 호출을 허용한다면 별도 동기화가 필요하다.
예를 들어 테스트 시작값으로 threatDecayPerSecond = 2.0과 도발의 즉시 위협도 30을 둘 수 있다. 이 값이 목표를 얼마나 오래 바꾸는지는 다른 점수 항과 기존 위협도에 달려 있으므로, 몬스터 생존 시간과 회피 수단을 포함한 플레이테스트로 조정한다.
Surrounding 패턴은 왜 슬롯 기반이어야 하는가?
목표 유저의 현재 위치만 추적하는 방식으로는 둘러싸기 위치를 직접 배정하지 않는다. 여러 몬스터가 같은 접근 방향을 선택할 수 있으며, 내비게이션 에이전트의 회피만으로 원하는 공격 간격이 보장되는 것은 아니므로 게임에 맞는 위치 배정과 검증을 추가할 수 있다.
슬롯 기반 Surrounding은 목표 주위에 제한된 공격 위치를 만들고 몬스터가 위치 자체를 예약하는 설계 패턴이다. 예를 들어 반경 1.8m에 몬스터 반경 0.45m인 구성에서 8개 슬롯을 테스트 시작안으로 둘 수 있다. 이 숫자만으로 충돌 없는 간격이나 공격 가능성이 보장되지는 않는다.
여기서는 Unity 3D 장면에서 Y를 높이 축으로 사용하고 지면의 XZ 평면에 슬롯을 배치한다고 가정한다. r은 공격 거리와 충돌 크기를 고려해 정할 목표 중심으로부터의 반경이다. 슬롯이 N개라면 θ_i = 2πi/N + offset처럼 각도를 정할 수 있으며, 개체별 오프셋은 겹침을 피하기 위한 설계 선택이다.

AI 몬스터 유저 둘러싸기를 구현하는 3단계
1. 파티 단위로 전투 역할을 먼저 배정한다
몬스터 개체가 독립적으로 판단하더라도 같은 전투 그룹의 역할을 CombatDirector 같은 조정자가 관리하는 설계를 고려할 수 있다. 아래 역할 및 수는 예시이며, 그룹 규모와 게임 플레이에 맞게 바꾼다.
| 역할 | 권장 비율 | 행동 |
|---|---|---|
Engager | 1~2명 | 정면 근접 슬롯을 점유하고 공격 유도 |
Flanker | 1~2명 | 측면 또는 후방 슬롯을 확보 |
RangedPressure | 0~2명 | 사선이 확보된 거리 유지 위치 선택 |
Reserve | 나머지 | 즉시 합류하지 않고 빈 슬롯 또는 이탈 유저 대응 |
역할을 매 프레임 재선정하지 않는 정책을 시험해 볼 수 있다. roleLockDuration 2~4초는 예시 시작값이며, 사망·경직·경로 실패·목표 이탈 등의 이벤트 때 예외 재배정을 허용할 수 있다. 재선정 주기와 점수 변동에 따라 목표가 진동할 수 있으므로 실제 이동을 확인한다.
2. 역할에 맞는 슬롯을 예약하고 유효성을 검사한다
예시 SlotManager는 슬롯마다 ReservedBy, ReservationExpireTime, RoleMask를 둘 수 있다. 예약 전에는 다음 조건을 프로젝트에 맞게 검사한다.
NavMesh.SamplePosition또는 사용하는 내비게이션 시스템으로 이동 가능한 지점을 찾는다.- 벽, 낭떠러지, 위험 지대 때문에 공격 애니메이션을 수행할 수 없는 위치는 제외한다.
- 다른 몬스터가 예약한 슬롯은 후보에서 제외한다.
- 역할에 맞는 후보 중 경로 비용이 낮은 슬롯을 선택한다.
public bool TryReserveSlot(Monster monster, Target target, out SurroundSlot slot)
{
// Assumes this manager is called serially on the game's owning thread.
var candidates = slots
.Where(s => s.IsAvailable(Time.time))
.Where(s => s.Allows(monster.Role))
.Where(s => s.IsReachable(target.Position))
.OrderBy(s => s.PathCost(monster.Position))
.ToList();
slot = candidates.FirstOrDefault();
if (slot == null) return false;
slot.ReservedBy = monster.Id;
slot.ReservationExpireTime = Time.time + 1.5f;
return true;
}
예약 만료는 넉백·경직·경로 막힘 뒤 슬롯을 다시 사용할 수 있게 하는 한 가지 정책이다. 실제 예시에서는 1.5초 후 만료시키며, 게임의 이동 속도와 경로 재탐색 시간에 맞춰 조정한다.
3. 짧은 주기가 아닌 이벤트와 쿨다운으로 재평가한다
목표와 슬롯을 매 프레임 다시 선택하는 정책은 점수 변화에 따라 방향 전환을 유발할 수 있다. 이벤트 기반 재평가와 0.5~1.0초 주기는 테스트할 수 있는 예시 설정이며, 게임의 전투 속도에 맞춰 조정한다.
- 현재 목표가 사망하거나 탐지 범위를 벗어남
- 예약 슬롯에 1.5초 이상 도달하지 못함
- 유저가 회피·돌진으로 포위 반경을 크게 벗어남
- 몬스터가 경직, 넉백, 군중 제어 상태에 들어감
- 파티의
Engager가 전멸하거나 전투 그룹이 분리됨
공정한 포위 전투를 위한 밸런싱 규칙
Surrounding 연출에서 여러 적의 공격이 겹칠 수 있다면, 동시 공격 수나 회피 창 같은 제한 장치를 시험할 수 있다. 아래 수치는 효과가 검증된 기준값이 아니라 예시 시작값이다.
| 제한 규칙 | 예시 파라미터 | 기대 효과 |
|---|---|---|
| 동시 공격 토큰 | 근접 2개, 원거리 1개 | 같은 시점의 공격 수를 제한하려는 예시 |
| 후방 슬롯 상한 | 최대 2개 | 후방 접근 수를 제한하려는 예시 |
| 공격 교대 시간 | 0.8~1.5초 | 회피 창을 시험하기 위한 예시 |
| 포위 반경 확장 | 3명 이상이면 1.8m → 2.6m | 간격과 시야 가림 영향을 테스트할 예시 |
| 탈출 반응 | 돌진·넉백 후 0.75초 재정렬 지연 | 탈출 기술의 체감 효과를 시험할 예시 |
AttackToken은 위치 예약과 공격 허가를 분리하는 설계 선택이다. 예를 들어 일부 Engager만 토큰을 받아 공격하고 나머지는 위협 동작이나 거리 유지 상태에 둔다. 준비 애니메이션이 실제 대응 기회를 제공하는지는 공격 시작 시점과 애니메이션 가독성을 플레이테스트로 확인한다.
멀티플레이에서 타깃 분산 기준은 무엇인가?
협동 게임에서 최고 Threat 유저를 우선 공격하면 탱커 역할이 두드러질 수 있지만, 다른 유저가 소외되는지는 전투 규칙에 달려 있다. 균등 분산은 탱커나 도발 스킬의 전략적 가치를 약화할 수도 있다.
권장 방식은 역할군별 정책을 다르게 두는 것이다.
- 일반 근접 몬스터:
Threat와 공격자 수 패널티를 함께 적용한다. - 정예 수호자: 도발과 최고 Threat를 강하게 따른다.
- 기습병: 후방 유저, 회복 직후 유저, 고립된 유저에 가중치를 둔다.
- 원거리 몬스터: 시야선과 사거리 유지 비용을 우선한다.
역할군별 정책은 적의 행동 차이를 만드는 방법 중 하나다. 유저가 그 차이를 학습할 수 있는지는 행동의 일관성과 표현을 테스트해 확인한다.
자주 묻는 질문 (FAQ)
Q. 몬스터가 몇 마리부터 Surrounding을 적용해야 하는가?
A. 고정된 수 기준은 없다. 근접 적이 여러 마리일 때 슬롯 예약이 겹침을 줄이는지 테스트하고, 적은 수라면 거리 유지와 공격 교대만으로 충분한지 전투 공간에서 확인한다.
Q. 모든 슬롯이 막혔으면 몬스터는 무엇을 해야 하는가?
A. 한 선택지는 새 슬롯을 강제로 만들지 않고 Reserve 상태로 전환하는 것이다. 짧은 이동 견제, 원거리 투사체, 다음 공격 토큰 대기처럼 역할에 맞는 대기 행동을 둘 수 있다.
Q. 길찾기 실패가 많으면 슬롯 수를 늘려야 하는가?
A. 먼저 슬롯 수보다 지형 유효성 검사와 예약 만료를 점검한다. 접근 불가능한 슬롯을 후보에 포함하면 슬롯을 늘려도 경로 실패와 진동이 반복된다.
정리
어그로 분산과 Surrounding을 설계할 때는 협동 공격의 의도를 유저가 읽고 대응할 수 있는지를 목표로 삼을 수 있다. ThreatTable, CombatDirector, SlotManager, AttackToken은 그 목표를 시험하기 위한 예시 구성 요소이며, 전투 밀도와 공정성은 플레이테스트와 게임별 지표로 평가해야 한다.
참고 자료
- Unity 2022.3 NavMesh Agent 매뉴얼
- Unity 2022.3 NavMesh.SamplePosition API
- Unity 2022.3 Transform 매뉴얼



