IronBird 개발일지 #3
Object Pool 구현 - Spawn/Destroy 비용 제거
Object Pool · ABulletPool · Game 스레드 25% 감소 · FPS +27%
🎯 목표
#2에서 의도적으로 남겨둔 SpawnActor/Destroy 반복 구조를 Object Pool로 교체한다. Before 수치를 미리 기록해뒀기 때문에 교체 후 정확한 Before/After 비교가 가능하다.
Before 수치 기록(#2) → Object Pool 구현 → After 수치 측정 → 차이 분석
📖 Object Pool이란?
게임에서 총알, 이펙트, 적 같은 오브젝트는 생성과 삭제가 빈번하게 반복된다. 매번 SpawnActor/Destroy를 호출하면 메모리 할당/해제 비용이 매 프레임 발생한다.
Object Pool은 오브젝트를 미리 일정 수량 만들어두고, 필요할 때 꺼내 쓰고 다 쓰면 삭제하지 않고 비활성화해서 다시 넣어두는 방식이다.
ABullet* Bullet = GetWorld()->SpawnActor<ABullet>(...);
Bullet->Destroy();
// After: Pool에서 꺼내 쓰고 반납
ABullet* Bullet = BulletPool->GetBullet(); // 비활성 총알 꺼냄
BulletPool->ReturnBullet(Bullet); // 비활성화 후 반납
🔧 구현 내용
ABulletPool 동작 흐름
for (int32 i = 0; i < PoolSize; i++)
{
ABullet* Bullet = GetWorld()->SpawnActor<ABullet>(...);
Bullet->SetActorHiddenInGame(true);
Bullet->SetActorEnableCollision(false);
Pool.Add(Bullet);
}
// 2. GetBullet(): 비활성 총알 반환. 없으면 새로 생성
for (ABullet* Bullet : Pool)
if (Bullet->IsHidden()) return Bullet;
// 3. ReturnBullet(): 비활성화 후 Pool 대기 상태로
Bullet->SetActorHiddenInGame(true);
Bullet->SetActorEnableCollision(false);
Bullet->SetActorTickEnabled(false);
모바일 관점: GetBullet()에서 TArray를 선형 탐색(O(n))하고 있다. 지금은 총알 30개라 문제없지만 오브젝트가 많아지면 TQueue나 인덱스 관리로 O(1) 접근으로 개선할 수 있다.
📊 Before / After 수치 비교
측정 환경: PIE, 총알 50개+ 동시 존재, 발사 간격 0.1초

핵심 결과: Game 스레드 25% 감소가 Object Pool의 직접적인 효과다. SpawnActor/Destroy 반복 시 발생하던 메모리 할당/해제 비용이 제거됐다. Draw 스레드 54% 감소는 오브젝트 재사용으로 렌더링 상태 변경 비용도 줄어든 추가 효과다.
💡배운 것
• Object Pool은 개념은 단순하지만 효과가 명확하다. 총알처럼 빈번하게 생성/삭제되는 오브젝트에 필수적인 패턴이다.
• 비활성화는 SetActorHiddenInGame + SetActorEnableCollision + SetActorTickEnabled 세 가지를 함께 처리해야 완전히 꺼진다.
• 현재 GetBullet()은 TArray 선형 탐색 O(n)이다. 오브젝트가 많아지면 TQueue로 교체해 O(1) 접근이 필요하다.
• 탄막 슈팅처럼 수백 발이 필요한 경우엔 AActor 풀링 자체를 버리고 Niagara 파티클이나 UInstancedStaticMeshComponent 기반으로 전환하는 게 맞다.
• 최적화는 반드시 수치로 증명해야 한다. 감으로 "빠를 것 같다"가 아니라 Before/After 측정이 필요하다.
📌 다음 작업
[IronBird #4] 적 스폰 시스템
위에서 아래로 내려오는 적 기체 스폰 매니저 구현. DataTable로 스테이지별 스폰 패턴 관리.
'개인프로젝트 > IronBird' 카테고리의 다른 글
| [IronBird #5] 보스 페이즈 + 적 3종류 + 충돌 시스템 구현 (0) | 2026.05.28 |
|---|---|
| [IronBird #4] 적 스폰 시스템 구현 (0) | 2026.05.28 |
| [IronBird #2] 배경 스크롤 + 총알 발사 구현 (0) | 2026.05.27 |
| [IronBird #1] - 플레이어 이동 + 터치 입력 구현 - UE5 C++ 탑뷰 슈팅게임 - Claude Code 활용기 (0) | 2026.04.20 |
| [IronBird #0] - 프로젝트 셋업 (GitHub · Git LFS · CLAUDE.md · Claude Code · MCP 서버) - Claude Code 활용기 (0) | 2026.04.15 |