[UE5] Enemy AI 원거리 공격을 위한 서버 데이터 기반 Projectile Manager 구현 - 2
2026. 6. 11. 21:47ㆍ구현
구현 1단계: 서버에서 원거리 공격 발사 시점을 감지하고, 총구에서 직선 탄도를 생성·수명 관리하는 것
- 공격 Montage Notify마다 정확히 한 발 생성된다.
- 무기의 S_Muzzle에서 시작한다.
- AI Target을 향해 직선으로 이동한다.
- 서버 Manager가 Actor 없이 구조체 배열로 관리한다.
- 수명이 끝나면 제거된다.
- Debug Draw로 궤적을 확인할 수 있다.
// 구현 흐름
ProjectileTypes
- 원거리 공격 GA가 투사체 Manager에 전달하는 발사 요청 정보 구조체
- 서버에서 관리되는 투사체 런타임 상태 정보 구조체
ProjectileManagerComponent
- FireProjectile: 새로운 투사체를 서버 배열에 등록한다.
- TickComponent: 서버에서 활성 투사체를 이동시키고 수명이 끝난 투사체를 제거한다. DebugLine 그림.
RunGameState
- GameState에 ProjectileManagerComponent를 등록한다.
EnemyAIController
- Blackboard에 저장된 현재 공격 대상을 반환한다.
EnemyWeaponBase
- 무기의 Muzzle 소켓의 Transform을 반환한다.
GA_EnemyAttackRanger
- 공격 횟수에 맞게:
몽타주 재생 후
MuzzleTransform 위치, Target 액터 위치, 공격 방향, 투사체 속도, 투사체 최대 수명 시간을
ProjectileManagerComponent의 FireProjectile의 매개변수로 넣고 실행한다.
구현 2단계: 서버 투사체 충돌 판정
- Sphere Sweep로 이동 구간 검사
- 벽, 바닥, 플레이어에 충돌
- 발사한 Enemy는 무시
- 충돌 지점 Debug 표시
- 충돌한 투사체 즉시 제거
// 구현 흐름
Custom Trace Channel 생성
- Default는 Ignore로 설정
- Preset 중 BlockAll, BlockAllDynamic, Character만 Block으로 처리
ProjectileType의 각 구조체 추가된 데이터 /
GA_EnemyAttackRanger에서 발사 요청으로 전달될 추가 데이터
- 투사체 충돌 반지름
- 투사체 Trace Channel
- 투사체를 발사한 SourceActor
ProjectileManagerComponent
- 충돌 검사 로직 추가:
- Trace로 움직이는 동선에 투사체의 현재 위치를 갱신시키며
플레이어, 벽, 바닥, 엄폐물 등에 Block된 경우 Hit 처리
- 충돌되지 않은 경우, 최대 수명 시간에 도달하면 투사체 제거
// Sweep 충돌 검사 옵션
FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(NSProjectile), false);
// 투사체를 발사한 Enemy 자신은 충돌 검사에서 제외
if (AActor* SourceActor = Projectile.SourceActor.Get())
{
QueryParams.AddIgnoredActor(SourceActor);
}
// 충돌 결과를 받을 구조체
FHitResult HitResult;
// Sweep 충돌 검사
const bool bHit = World->SweepSingleByChannel(
HitResult,
PreviousLocation,
NextLocation,
FQuat::Identity,
Projectile.TraceChannel,
FCollisionShape::MakeSphere(Projectile.Radius),
QueryParams
);
구현 3단계: 충돌 대상에게 GAS Damage GameplayEffect 적용
- 충돌 대상의 ASC 조회
- 발사자와 대상의 팀 확인
- HitResult를 Effect Context에 저장
- 기존 GEC_DamageExecution을 사용하는 Damage Effect 적용
- 벽 충돌에는 피해 없음
// 구현 흐름
ProjectileType의 각 구조체 추가된 데이터 /
GA_EnemyAttackRanger에서 발사 요청으로 전달될 추가 데이터
- Damage가 담긴 GameplayEffect 정보
ProjectileManagerComponent
- SourceActor로부터 발사자, 충돌 정보 추출해 Damage GameplayEffect와 함께
FGameplayEffectSpecHandle 형태로 TargetASC에 전달
- 같은 팀일 때는 피해 적용 X
현재는 몬스터의 공격이 명중 시점의 데미지로 들어가게끔 되어 있다. 만약 몬스터의 데미지가 버프 혹은 디버프를 받는다면 이미 발사한 투사체도 데미지가 버프 혹은 디버프된다.
좀 더 정확한 시점을 위해서는 발사 시점에 데미지가 결정되어야 한다고 보지만, 현재 GEC_DamageExecution 이라는 하나의 데미지 계산 로직을 플레이어와 몬스터가 공유하고 있었기에 섣불리 수정할 수 없다.
또한 몬스터에게 버프/디버프를 적용할지 말지에 대한 여부도 결정되지 않았기에 이에 대한 처리는 지금 할 것이 아니라고 생각이 들어 후순위로 미뤘다.
TODO:
몬스터 공격력 변경 또는 Pool 재사용이 도입되면
발사 시점 Damage Snapshot을 투사체 전용 경로로 구현한다.
공용 GEC_DamageExecution 변경 전 플레이어 공격 회귀 테스트 필요.
구현 4단계: Client RPC로 시각 투사체 Actor 로컬 생성
내용 정리 중...
'구현' 카테고리의 다른 글
| 26.06.26(금) (0) | 2026.06.26 |
|---|---|
| [UE5] Enemy AI 원거리 공격을 위한 서버 데이터 기반 Projectile Manager 구현 - 3 (0) | 2026.06.12 |
| [UE5] Enemy AI 원거리 공격을 위한 서버 데이터 기반 Projectile Manager 구현 - 1 (1) | 2026.06.10 |
| [UE5] FABRIK로 무기 소켓 기반 Left Hand IK 구현하기 (0) | 2026.06.09 |