오브젝트 풀링은 게임 내에서 자주 생성 및 파괴되는 오브젝트(총알, 적 캐릭터 등)을 미리 일정 수 만큼 생성해 풀에 보관해 두고, 필요할때마다 반환하는 최적화 기법이라고 한다.
오브젝트를 새로 만들고 파괴하는 비용을 줄여 성능 저하를 방지하는데 용이하다.
오브젝트 풀링 개념 정리
- 게임 중 자주 생성/제거되는 오브젝트를 미리 만들어 풀에 저장
- 필요항 때 꺼내 쓰고, 사용 후 비활성화 하여 다시 풀에 반환
- 매번 새로 만드는 대신 재사용하므로 메모리 할당/해제 비용과 가비지 컬렉션(GC) 부담 감소
- 총알, 이펙트, 적 등 무수히 많은 오브젝트들이 자주 생성/제거 되는 게임에 효과적이다.
// 헤더파일 ObjectPool.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ObjectPool.generated.h"
UCLASS()
class YOURGAME_API AObjectPool : public AActor
{
GENERATED_BODY()
public:
AObjectPool();
virtual void BeginPlay() override;
// 풀에서 오브젝트 꺼내기
AActor* GetPooledObject();
protected:
// 풀에 저장할 클래스 타입
UPROPERTY(EditAnywhere)
TSubclassOf<AActor> PooledObjectClass;
// 풀 크기
UPROPERTY(EditAnywhere)
int32 PoolSize = 20;
private:
// 실제로 저장되는 오브젝트 배열
TArray<AActor*> PoolArray;
};
// 소스파일 ObjectPool.cpp
#include "ObjectPool.h"
#include "Engine/World.h"
AObjectPool::AObjectPool()
{
PrimaryActorTick.bCanEverTick = false;
}
void AObjectPool::BeginPlay()
{
Super::BeginPlay();
for (int32 i = 0; i < PoolSize; i++)
{
if (PooledObjectClass)
{
AActor* NewObj = GetWorld()->SpawnActor<AActor>(PooledObjectClass, FVector::ZeroVector, FRotator::ZeroRotator);
if (NewObj)
{
NewObj->SetActorEnableCollision(false);
NewObj->SetActorHiddenInGame(true);
NewObj->SetActorTickEnabled(false);
PoolArray.Add(NewObj);
}
}
}
}
AActor* AObjectPool::GetPooledObject()
{
for (AActor* Obj : PoolArray)
{
if (Obj && !Obj->IsActorTickEnabled()) // 사용 중 아니면 반환
{
Obj->SetActorEnableCollision(true);
Obj->SetActorHiddenInGame(false);
Obj->SetActorTickEnabled(true);
return Obj;
}
}
// 풀에 없는 경우 nullptr 또는 새로 생성할 수도 있음
return nullptr;
}
- 사용법 요약
1. 게임 시작 시 오브젝트 풀러(AObjectPool)에서 지정한 클래스 타입의 액터를 미리 PoolSize만큼 생성해둠
2. 사용할 때 GetPooledObject() 호출해 비활성 상태인 오브젝트를 찾아 활성화 후 반환
3. 사용이 끝나면 다시 비활성화하여 풀에 돌려놓는 방식으로 재사용
- 정리
1. 오브젝트 풀링은 반복적인 오브젝트 생성/파괴 비용을 줄이는 최적화 기법
2. 게임 내 퍼포먼스(프레임 드랍, 메모리 할당 지연 등) 개선 효과 큼
3. 언리얼 C++에서는 풀을 클래스로 만들어 미리 액터를 생성하고 관리하는 방식
4. 꼭 풀 크기, 풀에 관리할 오브젝트 종류 등을 상황에 맞게 조절
'알아두면 좋은 것들(언리얼 관련 여러 잡다한 정보)' 카테고리의 다른 글
| BTTaskNode 에 존재하는 Task들 (0) | 2025.09.15 |
|---|---|
| SweepMultiByChannel() 을 이용한 액터 감지 (1) | 2025.08.25 |
| TSubclassOf<> 에 대하여 (1) | 2025.08.08 |
| 블루프린트에 있는 캐릭터 Move를 C++ 로 옮기기 (1) | 2025.08.05 |
| 7번 과제에서 했던 회전 행렬 구하는 FRotationMatrix 에 대하여 (0) | 2025.07.17 |