KoreanFoodie's Study
언리얼 애셋 레퍼런스(Hard Reference, Soft Reference) 본문
Hard Reference vs Soft Reference
A 가 B 를 하드 참조(Hard Reference) 하고 있다고 하면, A 가 로딩될때 B 도 로딩된다. 반면 A 가 B 를 약하게 참조(Soft Reference) 한다면, B 애셋의 경로 등을 string 의 형태로 갖고 있다는 뜻이다.
먼저 하드 참조부터 살펴보도록 하자.
Direct Property Reference (Hard Reference)
UPROPERTY 를 붙여 변수를 선언하면, 해당 변수(혹은 블루프린트)가 로드될 때 이에 대응하는 애셋 또한 로딩된다. 예시 코드를 보자.
/** construction start sound stinger */
UPROPERTY(EditDefaultsOnly, Category=Building)
USoundCue* ConstructionStartStinger;
Construction Time Reference (Hard Reference)
다음 예시는 생성자에서 ConstructorHelpers 클래스를 이용해 애셋을 로딩하는 예제이다. 추후 애셋을 바꾸지 않을 경우, static 키워드를 붙여준다.
/** gray health bar texture */
UPROPERTY()
class UTexture2D* BarFillTexture;
AStrategyHUD::AStrategyHUD(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer)
{
static ConstructorHelpers::FObjectFinder<UTexture2D> BarFillObj(TEXT("/Game/UI/HUD/BarFill"));
assert(nullptr != BarFillObj);
BarFillTexture = BarFillObj.Object;
}
만약 애셋을 찾지 못했을 경우 nullptr 를 리턴한다. assert 로 애셋이 제대로 로드되었는지 체크해주는 습관을 들이는 것이 좋다.
이제 약한 참조의 예시를 보자.
Indirect Property Reference
비동기 애셋 로딩에서 다루었던 것처럼, FSoftObjectPath 를 이용해 경로를 보관한다. 그 후 TSoftObjectPtr 를 사용해 템플릿화된 코드를 저장한다. 실제로 애셋을 로딩할 때는 LoadObject<>( ) 메서드를 호출해야 한다. 예제 코드를 보자.
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=Building)
TSoftObjectPtr<UStaticMesh> BaseMesh;
UStaticMesh* GetLazyLoadedMesh()
{
if (BaseMesh.IsPending())
{
const FSoftObjectPath& AssetRef = BaseMesh.ToStringReference();
BaseMesh = Cast< UStaticMesh>(Streamable.SynchronousLoad(AssetRef));
}
return BaseMesh.Get();
}
IsPending 메소드를 사용하면 해당 애셋이 로딩되었는지 아닌지를 알 수 있다.
Find / Load Object
UPROPERTY 를 이용하지 않고, 애셋과 경로 정보를 가지고 런타임에서 직접 애셋을 로드할 수도 있다. 만약 이미 로드된 애셋(혹은 UObject) 을 찾는다면 FindObejct<>( ) 를 사용하면 된다. 만약 로드되지 않은 애셋을 로드하고 싶으면 LoadObject<>( ) 를 사용한다. (내부적으로 LoadObject 는 FindObject 와 같은 기능을 먼저 수행한다. 로드하려면 일단 찾아야 하니까!) 예제 코드를 보자.
AFunctionalTest* TestToRun = FindObject<AFunctionalTest>(TestsOuter, *TestName);
GridTexture = LoadObject<UTexture2D>(NULL, TEXT("/Engine/EngineMaterials/DefaultWhiteGrid.DefaultWhiteGrid"), NULL, LOAD_None, NULL);
타입에 맞게 로드를 해 보자.
DefaultPreviewPawnClass = LoadClass<APawn>(NULL, *PreviewPawnName, NULL, LOAD_None, NULL);
/* Above code is same as below codes */
DefaultPreviewPawnClass = LoadObject<UClass>(NULL, *PreviewPawnName, NULL, LOAD_None, NULL);
if (!DefaultPreviewPawnClass->IsChildOf(APawn::StaticClass()))
{
DefaultPreviewPawnClass = nullptr;
}
'Game Dev > Unreal C++ : Study' 카테고리의 다른 글
언리얼 블렌드 스페이스 (Blendspace) (0) | 2022.04.06 |
---|---|
언리얼 애셋 레지스트리(Asset Registry) (0) | 2022.04.04 |
언리얼 코어 리다이렉트 (Core Redirect) (0) | 2022.04.04 |
언리얼 비동기 애셋 로딩 (Asynchronous Loading) (0) | 2022.04.04 |
언리얼 어설트 정리 (assert, verify, ensure) (0) | 2022.04.04 |