IronBird 개발일지 #4
적 스폰 시스템 구현
Object Pool · 충돌 처리 · 터널링 · bSweep
🎯 목표
위에서 아래로 내려오는 적 기체를 스폰하고, 플레이어 총알과 충돌 시 처리한다. #3에서 증명한 Object Pool을 처음부터 적용해 Spawn/Destroy 비용을 원천 차단한다.
#3에서 Spawn/Destroy의 문제를 수치로 확인했고, 적 스폰 시스템 설계 시 처음부터 Object Pool을 적용했다.
🔧 구현 내용
Enemy::OnOverlapBegin(총알 감지)
→ HitBullet->ReturnToPool() // 총알 → BulletPool 반납
→ this->ReturnToPool() // 적 → EnemyPool 반납


📖 터널링(Tunneling)이란?
고속으로 이동하는 오브젝트가 충돌 감지를 건너뛰는 현상이다. 물리 엔진은 매 프레임마다 오브젝트의 위치를 체크하는데, 오브젝트가 한 프레임에 이동하는 거리가 충돌 대상의 두께보다 크면 충돌 판정 없이 통과해버린다.
IronBird에서 발생한 상황:
총알 이동 속도: 1500cm/s30fps 기준 프레임당 이동 거리: 50cm
적 큐브 두께 (scale 0.5): 50cm
→ 한 프레임에 적을 완전히 통과 → Overlap 이벤트 미발생
AddActorLocalOffset(Delta);
// After: bSweep=true로 이동 경로 상 충돌 감지
AddActorLocalOffset(Delta, true); // bSweep=true
모바일 관점 메모: bSweep=true는 이동 경로를 물리 엔진에서 추적하므로 단순 위치 업데이트보다 연산 비용이 크다. 총알처럼 수가 많은 오브젝트에 남용하면 모바일에서 부담이 된다. 총알 수가 매우 많은 탄막 슈팅이라면 LineTrace 기반 충돌 처리가 더 효율적인 대안이다.
🔥 트러블슈팅
문제 1. Z값 불일치로 충돌 미발생
원인: Enemy 스폰 Z=0 고정, 총알 Z=플레이어 위치 기준으로 서로 달랐다. 탑뷰라 눈으로는 겹쳐 보이지만 3D 공간에서 콜리전 박스가 실제로 겹치지 않음.
해결: EnemySpawner에서 스폰 Z값을 GetPlayerPawn()->GetActorLocation().Z로 동기화.
문제 2. 터널링으로 Overlap 이벤트 미발생
원인: 총알 속도 1500cm/s, 30fps 기준 프레임당 50cm 이동. 적 큐브 두께도 50cm라 한 프레임에 완전히 통과.
해결: AddActorLocalOffset(Delta, true) bSweep=true로 이동 경로 상 충돌 감지.
문제 3. ObjectType 충돌 채널 미분리
원인: Enemy/Bullet 모두 기본 ECC_WorldDynamic으로 동일 채널. UE5 Chaos에서 같은 채널끼리 간헐적 감지 실패 가능.
해결: Enemy에 SetCollisionObjectType(ECC_Pawn) 추가로 채널 분리.
문제 4. 이중 처리 방지
원인: Overlap 이벤트 연속 발생 시 이미 반납된 Enemy/Bullet에 중복 ReturnToPool() 호출 가능.
해결: if (IsHidden()) return guard 추가.
💡 배운 것
• 탑뷰에서 눈으로 겹쳐 보여도 Z축이 다르면 충돌이 발생하지 않는다. 3D 공간에서 생각해야 한다.
• 터널링은 고속 오브젝트에서 반드시 고려해야 한다. bSweep=true가 해결책이지만 연산 비용이 있으므로 남용은 금물이다.
• 충돌 채널은 오브젝트 타입별로 명시적으로 분리해야 한다. 기본값에 의존하면 간헐적 버그가 발생한다.
• Pool 반납 시 이중 처리 방지 guard는 필수다. Overlap 이벤트는 연속 발생할 수 있다.
📌 다음 작업
[IronBird #5] 보스 페이즈 구현
3페이즈 패턴 전환 보스 구현. HP 비율에 따라 이동 패턴과 공격 패턴이 바뀌는 상태머신 설계.
'개인프로젝트 > IronBird' 카테고리의 다른 글
| [IronBird #6] 메인화면 + 점수 시스템 + 게임오버/클리어 (0) | 2026.05.28 |
|---|---|
| [IronBird #5] 보스 페이즈 + 적 3종류 + 충돌 시스템 구현 (0) | 2026.05.28 |
| [IronBird #3] Object Pool 구현 - Spawn/Destroy 비용 제거 (0) | 2026.05.28 |
| [IronBird #2] 배경 스크롤 + 총알 발사 구현 (0) | 2026.05.27 |
| [IronBird #1] - 플레이어 이동 + 터치 입력 구현 - UE5 C++ 탑뷰 슈팅게임 - Claude Code 활용기 (0) | 2026.04.20 |