액터를 매번 SpawnActor/Destroy 하지 않고
미리 생성해둔 객체들을 재활용(Reuse) 하는 방식
성능 이득: GC 감소, 메모리 할당 최소화, 프레임 드랍 방지
풀 생성: 시작할 때 액터를 N개 미리 생성해 비활성화 상태로 저장
요청 시 꺼냄: 필요한 순간에 활성화하고, 위치/상태 초기화
사용 후 반환: 다 쓰면 다시 비활성화하고 풀에 되돌림
UCLASS()
class ABullet : public AActor
{
GENERATED_BODY()
public:
void ActivateBullet(FVector Location);
void DeactivateBullet();
};
UCLASS()
class ABulletPoolManager : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TSubclassOf<ABullet> BulletClass;
UPROPERTY(EditAnywhere)
int32 PoolSize = 20;
TArray<ABullet*> BulletPool;
virtual void BeginPlay() override;
ABullet* GetBullet();
void ReturnBullet(ABullet* Bullet);
};
void ABulletPoolManager::BeginPlay()
{
Super::BeginPlay();
for (int32 i = 0; i < PoolSize; ++i)
{
ABullet* Bullet = GetWorld()->SpawnActor<ABullet>(BulletClass, FVector::ZeroVector, FRotator::ZeroRotator);
Bullet->DeactivateBullet();
BulletPool.Add(Bullet);
}
}
ABullet* ABulletPoolManager::GetBullet()
{
for (ABullet* Bullet : BulletPool)
{
if (!Bullet->IsActorTickEnabled()) // 간단한 비활성화 체크
{
Bullet->ActivateBullet(SomeSpawnLocation);
return Bullet;
}
}
return nullptr; // 풀에 남은게 없을 경우
}
void ABulletPoolManager::ReturnBullet(ABullet* Bullet)
{
if (Bullet)
{
Bullet->DeactivateBullet();
}
}
총알, 이펙트, 파편 등 성능 이슈 많은 액터에 적극 사용
GC 호출 횟수도 줄어들어 런타임 성능 향상
TQueue, TArray, TObjectPtr 등으로 풀 구조 다양하게 가능
나이아가라 파티클도 Deactivate() & Activate()로 재활용 가능함
맵에 몇 개만 존재하고
자주 파괴되지 않거나, 재사용 빈도가 낮은 경우
예: 맵에 고정된 상자, 유니크한 무기 드롭 등
이런 경우엔 그냥 SpawnActor로 생성하고 Destroy()로 제거해도 충분. 오히려 풀링은 오버킬일 수 있다.
초당 여러 개 생성/삭제 ->> 총알, 폭발, 이펙트, 타격 이펙트
여러 번 재사용됨 ->> 몬스터 리스폰, 수류탄
짧은 시간 안에 많이 생성됨 ->> UI 팝업, 데미지 텍스트, 파티클