언리얼 스마트 포인터 라이브러리
언리얼 엔진에서는 C++의 스마트 포인터와 유사한 방식의 커스텀 포인터 라이브러리를 구현해놓았다.
이 포인터들은 Unreal Engine의 메모리 안전성과 참조 관리 기능을 활용할 수 있도록 만들어졌으며, 각각의 목적과 사용 방식이 다르다.
1. TSharedPtr
참조하고 있는 객체를 여러 포인터가 공유할 수 있으며, 마지막 하나가 파괴될 때 객체가 소멸된다. std::shared_ptr와 유사하지만, Unreal의 메모리 시스템과 통합되어 있다.
2. TWeakPtr
위크 포인터는 쉐어드 포인터와 비슷하지만 참조하는 오브젝트를 소유하지 않기 때문에 생명 주기에 영향을 주지 않는다. 객체에 대한 비소유권 참조이기 때문에 언제든지 Null이 될 수 있다. 순환 참조 방지에 주로 사용된다.
3. TUniquePtr
소유권이 하나뿐인 스마트 포인터로 복사 불가능하고 이동만 가능하다. std::unique_ptr와 유사하다.
단, 언리얼 오브젝트는 게임 코드에 더 최적화된 별도의 메모리 추적 시스템을 사용하기 때문에 이러한 클래스들은 'UObject' 시스템과 사용할 수 없습니다. (문서 참조)
언리얼 오브젝트에 대한 스마트 포인터
언리얼엔진의 UObject 클래스는 별도의 메모리 추적 시스템을 이용하기 때문에 위에서 소개한 포인터와는 다른 포인터를 사용해야한다.
이를 위해 엔진에서는 UObject 파생 클래스를 위한 특별한 포인터가 존재한다.
TObjectPtr
Strong Reference(강한 참조)방식의 포인터이다.
액터가 메모리에 로딩될 때, TObjectPtr이 참조하고 있는 객체에 대해서도 같이 로드된다.
#include "UObjectTest.generated.h"
UCLASS()
class UE5PROGRAMMING_API AMyActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TObjectPtr<UStaticMeshComponent> MeshComponent;
};TSoftObjectPtr
Path-based Weak Reference(경로 기반의 약한 참조)방식의 포인터이다.
에디터 또는 런타임에서 리소스를 바로 메모리에 로드하지 않고, 필요할 때 로드할 수 있다. 이를 활용하여 Lazy Loading(지연 로딩), Asynchronous Loading(비동기 로딩) 등이 가능하다.
FSoftObjectPath 기반으로 동작하며, 경로 기반으로 객체를 참조한다.
또한 객체가 로딩되었는지 확인하는 유효성 검사 작업이 필요하다.
리소스가 언로드 되더라도(메모리에서 없어져도) 참조는 유지된다.
#include "UObjectTest.generated.h"
UCLASS()
class UE5PROGRAMMING_API AMyActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TSoftObjectPtr<UTexture2D> TexturePtr;
};void AMyActor::LoadTexture()
{
// 객체가 존재하는 지 확인
if(TexturePtr.IsPending())
{
// 동기 로딩
if(Utexture2D* Texture = TexturePtr.LoadSynchoronous())
{
// 텍스쳐 사용
...
}
// 비동기 로딩
else
{
TexturePtr.LoadAsync();
}
}
}TWeakObjectPtr
Weak Reference(약한 참조)방식의 포인터이다.
객체의 소유권을 가지지 않기 때문에, 객체 수명에 영향을 주지 않는다. 따라서 순환 참조 문제를 해결할 수 있다.
만약 TWeakObjectPtr로 참조중인 객체가 GC(Garbage Collection)에 의해 제거될 경우, 메모리에서도 참조가 해제된다.
객체가 존재하지 않을 수 있기 때문에 반드시 유효성 검사 작업이 필요하다.
#include "UObjectTest.generated.h"
UCLASS()
class UE5PROGRAMMING_API AMyActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TWeakObjectPtr<AActor> WeakActor;
};
...
// 객체가 존재하는 지 확인
if (WeakActor.IsValid())
{
WeakActor->DoSomething();
}요약
| 종류 | 참조 방식 | 특징 | |-|-|-| | TObjectPtr | Strong Reference | Garbage Collection 지원, Serialization 및 네트워크 복사 지원 | TSoftObjectPtr | Path-based Weak Reference | Lazy Loading(지연 로딩), Asynchoronous Loading(비동기 로딩) 지원 | TWeakObjectPtr | Weak Reference | 순환 참조 방지, 캐시 및 임시 참조 |