이 글에서는 Unreal Engine에서 블루프린트 클래스 로드와 스폰을 다루며, 이를 위한 함수인 StaticLoadClass
, LoadObject
의 차이점과 사용법을 살펴보겠습니다.
StaticLoadClass
와 LoadObject
의 기본 사용법Unreal Engine에서 블루프린트를 로드해 클래스를 스폰할 때 StaticLoadClass
나 LoadObject
를 주로 사용하게 됩니다. 이들 함수는 콘텐츠 브라우저의 경로를 통해 블루프린트를 코드에서 참조 가능하도록 만들어주며, 필요한 타입의 객체나 클래스로 변환할 수 있도록 지원합니다.
블루프린트 클래스 경로는 다음 형식이어야 합니다. 경로 끝에 _C
접미사가 반드시 포함되어야 합니다.
"/Game/Blueprints/MyBlueprint.MyBlueprint_C"
FString ClassPath = "/Game/Blueprints/MyBlueprint.MyBlueprint_C";
UClass* LoadedClass = StaticLoadClass(AActor::StaticClass(), nullptr, *ClassPath);
if (LoadedClass)
{
UE_LOG(LogTemp, Log, TEXT("블루프린트 클래스 로드 성공: %s"), *LoadedClass->GetName());
}
else
{
UE_LOG(LogTemp, Error, TEXT("블루프린트 클래스 로드 실패: 경로를 확인하세요."));
}
TSubclassOf
에 로드한 클래스 저장하기블루프린트를 경로를 통해 TSubclassOf
타입으로 로드하면, 여러 번 사용할 수 있으며 SpawnActor
로 쉽게 스폰할 수 있습니다. TSubclassOf
는 특정 클래스의 하위 클래스를 참조하도록 설계되어 있어, 캐스팅이 용이하고 오류 가능성이 적습니다.
TSubclassOf<AActor> ItemClass;
// 경로에서 클래스 로드 후 TSubclassOf에 저장
FString BlueprintPath = "/Game/Blueprints/MyWeaponBlueprint.MyWeaponBlueprint_C";
UClass* LoadedClass = StaticLoadClass(AActor::StaticClass(), nullptr, *BlueprintPath);
if (LoadedClass && LoadedClass->IsChildOf(AActor::StaticClass()))
{
ItemClass = LoadedClass;
UE_LOG(LogTemp, Log, TEXT("클래스가 TSubclassOf에 저장되었습니다."));
}
else
{
UE_LOG(LogTemp, Error, TEXT("클래스 로드 실패 또는 AActor의 하위 클래스가 아닙니다."));
}
// 저장된 클래스를 통해 스폰
if (ItemClass)
{
AActor* SpawnedActor = GetWorld()->SpawnActor<AActor>(ItemClass);
if (SpawnedActor)
{
UE_LOG(LogTemp, Log, TEXT("스폰 성공: %s"), *SpawnedActor->GetName());
}
else
{
UE_LOG(LogTemp, Error, TEXT("스폰 실패: ItemClass가 올바르지 않습니다."));
}
}
이렇게 하면 TSubclassOf
타입의 ItemClass
를 이용해 손쉽게 객체를 스폰할 수 있습니다.
Load
함수들: StaticLoadClass vs LoadObject vs StaticLoadObjectUnreal Engine에서 리소스를 로드할 때 사용하는 StaticLoadClass
, LoadObject
, StaticLoadObject
는 각기 다른 목적과 특징을 가지고 있습니다. 이 함수들의 차이와 사용 예제를 비교하여 언제 어떤 함수를 사용해야 하는지에 대해 정리해봤습니다.
StaticLoadClass
는 UClass를 로드하는 함수로, 블루프린트 클래스를 로드할 때 주로 사용됩니다. StaticLoadClass
는 클래스의 타입을 기반으로만 작동하기 때문에 객체 인스턴스를 생성하는 것은 불가능하며, 클래스 자체만을 가져옵니다.
FString ClassPath = "/Game/Blueprints/test.test_C";
UClass* LoadedClass = StaticLoadClass(AActor::StaticClass(), nullptr, *ClassPath);
UClass
(클래스 정보 자체)SpawnActor
등으로 객체를 생성할 준비를 할 때LoadObject
는 특정 객체를 로드할 때 사용하는 함수로, StaticLoadClass
와 달리 UObject 타입의 인스턴스를 직접 로드할 수 있습니다. 경로에서 텍스처, 사운드, 메시와 같은 실제 리소스를 로드하여 사용할 때 씁니다.
FString TexturePath = "/Game/Textures/testTexture";
UTexture2D* Texture = LoadObject<UTexture2D>(nullptr, *TexturePath);
if (Texture)
{
UE_LOG(LogTemp, Log, TEXT("텍스처 로드 성공"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("텍스처 로드 실패"));
}
UObject
타입의 인스턴스 (예: UTexture2D, USoundBase 등)StaticLoadObject
는 LoadObject
와 비슷한 기능을 하지만, 내부에서 객체 타입에 대한 고정된 클래스 정보가 필요할 때 주로 사용합니다. 따라서 LoadObject
가 주로 사용되지만, StaticLoadObject
는 리소스를 명시적으로 고정하여 로드할 때 더 선호됩니다.
FString MeshPath = "/Game/Meshes/testMesh";
UStaticMesh* Mesh = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), nullptr, *MeshPath));
if (Mesh)
{
UE_LOG(LogTemp, Log, TEXT("메시 로드 성공"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("메시 로드 실패"));
}
UObject
타입의 인스턴스 (다만 LoadObject
와의 명확한 차이 없음)함수 | 대상 | 주용도 | 사용 예 |
---|---|---|---|
StaticLoadClass | UClass | 클래스 로드 | 블루프린트 클래스 로드 및 스폰 준비 |
LoadObject | UObject | 객체 인스턴스 로드 | 텍스처, 사운드, 메시 등 리소스 로드 |
StaticLoadObject | UObject | 객체 인스턴스 로드 (타입 고정) | 특정 타입으로 명확히 리소스를 로드 |
이 표를 참고하여 프로젝트의 요구 사항에 맞는 Load
함수를 선택하면, 효율적이고 최적화된 코드 작성이 가능합니다.
Unreal Engine에서 StaticLoadClass
와 LoadObject
는 특정 목적에 맞게 설계된 함수들이기 때문에, 올바르지 않은 용도로 사용하게 되면 오류가 발생할 수 있습니다.
StaticLoadClass
를 사용해 텍스처, 사운드, 메시 등 리소스를 로드할 경우StaticLoadClass
는 UClass
타입의 데이터를 로드하기 위한 함수이므로, 텍스처, 사운드, 메시 등 리소스를 로드하려고 하면 실패하거나 타입 불일치 오류가 발생합니다. StaticLoadClass
는 객체 인스턴스가 아닌 클래스 정보만 로드하기 때문에, 이를 통해 직접적인 리소스(예: UTexture2D
나 USoundBase
등) 접근은 불가능합니다.
예시 코드에서 잘못된 사용 예를 보면:
// 잘못된 사용: 텍스처 로드에 StaticLoadClass 사용
FString TexturePath = "/Game/Textures/MyTexture";
UTexture2D* Texture = Cast<UTexture2D>(StaticLoadClass(UTexture2D::StaticClass(), nullptr, *TexturePath));
위 코드는 다음과 같은 오류를 발생시킬 수 있습니다.
Texture
는 항상 nullptr
이 반환됩니다."Cannot find class"
나 "Failed to load class"
와 같은 오류 메시지가 출력됩니다.따라서 텍스처와 같은 리소스를 로드할 때는 반드시 LoadObject<UTexture2D>(nullptr, *TexturePath)
와 같은 적절한 함수를 사용해야 합니다.
LoadObject
를 사용해 블루프린트 클래스 로드 및 스폰 준비를 할 경우반대로, LoadObject
는 UObject
인스턴스를 직접 로드하는 데 사용되므로, LoadObject<UClass>(nullptr, *ClassPath)
형태로 블루프린트 클래스를 로드하려 하면 실제 객체 인스턴스가 아닌 클래스 정보만 필요한 경우에 불필요한 인스턴스를 생성하려고 시도할 수 있습니다.
예를 들어, 블루프린트 클래스를 로드하는데 LoadObject
를 사용하면 런타임에서 다음과 같은 문제가 발생할 수 있습니다.
// 잘못된 사용: 블루프린트 클래스 로드에 LoadObject 사용
FString BlueprintPath = "/Game/Blueprints/MyBlueprint.MyBlueprint_C";
UClass* MyClass = LoadObject<UClass>(nullptr, *BlueprintPath);
귀찮지만 UBluePrintGeneratedClass로 다음처럼 사용해야합니다.
FString BlueprintPath = "/Game/Blueprints/MyBlueprint.MyBlueprint_C";
UBluePrintGeneratedClass* LoadedBP = LoadObject<UClass>(nullptr, *BlueprintPath);
if(LoadedBP)
{
testBlueprintClass* _blueprintclass = Cast<testBlueprintClass>(LoadedBP);
}
문제점:
LoadObject
는 인스턴스를 생성하려고 시도하지만, UClass
는 인스턴스화할 수 없는 타입이므로 불필요한 리소스 사용으로 이어질 수 있습니다.MyClass
는 항상 nullptr
일 가능성이 높으며, 이로 인해 런타임에서 오류 로그가 생성될 수 있습니다.UClass
를 LoadObject
로 직접 로드할 수 없다는 점을 알립니다.StaticLoadClass
: 클래스 정보(즉, UClass
)만 로드하며, 인스턴스화되지 않습니다. 블루프린트 클래스를 로드하여 스폰 준비를 할 때 적합합니다.LoadObject
: 특정 객체 인스턴스(예: 텍스처, 사운드, 메시 등)를 로드할 때 사용하며, 클래스 자체보다는 개별 리소스 사용 시 유용합니다.잘못사용할 경우 오류 로그가 생성되거나, NULL 참조로 인한 크래시와 같은 문제가 발생할 수 있습니다.
Unreal Engine에서 블루프린트 클래스를 로드하고 활용하는 방법은 게임 개발에서 매우 중요합니다. StaticLoadClass
를 이용해 TSubclassOf
로 클래스를 관리하고, 다양한 Load
함수들의 차이를 이해하고 적절히 활용함으로써 큰 오류를 미리 방지할 수 있습니다.
다음에는 UBluePrintGeneratedClass, UClass, UObject에 대해서 더 자세하게 알아볼 예정입니다.