
게임 프로젝트가 커질수록 수많은 Asset을 관리해야 한다.
캐릭터 Mesh, 애니메이션, 사운드, UI, 이펙트 등 다양한 Asset이 서로 참조 관계를 가지게 된다.
이때 중요한 문제 중 하나는 Asset이 언제 메모리에 로드되는가이다.
만약 하나의 객체가 여러 Asset을 직접 참조하고 있다면, 해당 객체가 로드되는 순간 관련된 Asset들도 함께 메모리에 올라가게 된다.
프로젝트 규모가 커질수록 이러한 구조는 다음과 같은 문제를 만들 수 있다.
이러한 문제를 해결하기 위해 Unreal Engine에서는 Soft Reference라는 참조 방식을 지원한다.
Soft Reference는 실제 Asset을 즉시 로드하지 않기 때문에 Asset 로딩 시점을 개발자가 제어할 수 있다.
이러한 특징 때문에 Soft Reference는 대규모 콘텐츠 관리나 Data Driven Design 구조에서 매우 중요한 역할을 한다.
Soft Reference의 특징을 이해하기 위해서는 먼저 기본적인 Asset 참조 방식인 Hard Reference와의 차이를 살펴볼 필요가 있다.
예를 들어 캐릭터 선택 UI에서 여러 캐릭터의 목록을 표시하는 상황을 생각해보자.
이때 캐릭터의 이름이나 아이콘만 필요할 뿐, 실제 SkeletalMesh는 필요하지 않을 수 있다.
하지만 캐릭터 데이터가 다음과 같이 Hard Reference로 구성되어 있다면 문제가 발생한다.
UCLASS()
class UCharacterData : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FName Name;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UTexture2D* Icon;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
USkeletalMesh* Mesh;
};
이 구조에서는 UCharacterData가 로드되는 순간 SkeletalMesh도 함께 로드된다.
void UCharacterListWidget::Init(const TArray<UCharacterData*>& CharacterList)
{
for (UCharacterData* Data : CharacterList)
{
// Character Widget 추가
}
}
UI에서는 Mesh를 사용하지 않음에도 불구하고, 다음과 같이 모든 Mesh가 로드된다.
CharacterListWidget
├── CharacterData A → SkeletalMesh 로드됨
├── CharacterData B → SkeletalMesh 로드됨
├── CharacterData C → SkeletalMesh 로드됨
...
결과적으로 단순히 UI를 띄우는 것만으로도 모든 캐릭터의 SkeletalMesh가 메모리에 올라가게 된다.
Soft Reference는 Asset을 직접 참조하지 않고 Asset의 경로(Path)만을 저장한다.
UCLASS()
class UCharacterData : public UPrimaryDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FName Name;
UPROPERTY(EditAnywhere, BlueprintReadOnly)
UTexture2D* Icon;
// Soft Reference
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TSoftObjectPtr<USkeletalMesh> Mesh;
};
이제 UCharacterData는 SkeletalMesh 자체를 들고 있는 것이 아니라 Asset의 경로만 저장하게 된다.
Mesh는 이제 실제로 필요한 시점, 즉 캐릭터를 스폰할 때 로드한다.
void AMyCharacter::Init(UCharacterData* Data)
{
if (Data->Mesh.IsValid())
{
GetMesh()->SetSkeletalMesh(Data->Mesh.Get());
}
else
{
// 동기 로딩 (예시)
USkeletalMesh* LoadedMesh = Data->Mesh.LoadSynchronous();
GetMesh()->SetSkeletalMesh(LoadedMesh);
}
}
Unreal Engine에서 Soft Reference는 참조 대상에 따라 두 가지 형태로 나뉜다.

Soft Object Reference는 Asset Object 자체를 참조하는 방식이다.
위에서 언급했던 예시가 바로 Soft Object Reference에 해당된다.
UPROPERTY(EditAnywhere)
TSoftObjectPtr<USkeletalMesh> Mesh;
Soft Class Reference는 UClass를 참조하는 방식이다.
즉, 객체의 타입 자체를 Soft Reference로 관리하는 개념이다.
UPROPERTY(EditAnywhere)
TSoftClassPtr<AActor> ActorClass;
Hard Reference로 Class를 참조할 경우, 해당 Class는 즉시 메모리에 로드된다.
하지만 Soft Class Reference를 사용하면 Class를 로드하지 않고도 타입 정보를 유지할 수 있다.
Soft Class Reference는 단순히 “타입 비교” 용도로도 유용하다.
예를 들어 특정 Object의 클래스가 특정 리스트에 포함되는지 확인한다고 가정해보자.
이 경우 모든 클래스를 미리 로드할 필요 없이, Object의 Class를 Soft Reference로 변환하여 비교할 수 있다.