에셋 레지스트리는 언리얼 엔진 에디터의 핵심 기능 중 하나로, 프로젝트 내 모든 에셋에 대한 메타데이터를 수집하고 관리한다.
이 정보는 에셋이 실제로 메모리에 로드되지 않은 상태에서도 접근 가능하며, 에디터 시작 시 비동기적으로 수집된다.
콘텐츠 브라우저는 에셋 레지스트리의 주요 사용자이지만, 에디터의 다른 시스템이나 플러그인, 심지어 일부 런타임 기능에서도 활용될 수 있다.
에셋 레지스트리는 에셋의 경로, 클래스, 특정 프로퍼티 값 (태그) 등을 포함하여, 효율적인 에셋 검색, 필터링 및 관리를 지원한다.
주요 기능 및 사용법
- 에셋 목록 구하기 특정 조건에 맞는 에셋 목록을 조회하기 위해서는 먼저 에셋 레지스트리 모듈을 로드해야 한다. FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry")를 통해 모듈 인스턴스를 획득한 후, IAssetRegistry 인터페이스의 함수들을 사용한다.
- GetAssetsByClass(ClassName, OutAssetData, bSearchSubClasses): 특정 클래스 및 그 파생 클래스(bSearchSubClasses가 true인 경우)에 해당하는 모든 에셋의 FAssetData 목록을 반환한다.
-
C++
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry"); IAssetRegistry& Registry = AssetRegistryModule.Get(); // 인터페이스 획득 TArray<FAssetData> AssetDataList; FName StaticMeshClassName = UStaticMesh::StaticClass()->GetFName(); // FName으로 클래스 이름 전달 Registry.GetAssetsByClass(StaticMeshClassName, AssetDataList, true); // 파생 클래스 포함 검색
- GetAssetsByPath(PathName, OutAssetData, bRecursive): 지정된 경로 및 그 하위 경로(bRecursive가 true인 경우)에 위치한 모든 에셋의 FAssetData 목록을 반환한다.
-
C++
// 예시: /Game/MyFolder 경로의 모든 에셋 검색 Registry.GetAssetsByPath(TEXT("/Game/MyFolder"), AssetDataList, true);
- GetAssetByObjectPath(ObjectPath, OutAssetData): 단일 에셋의 전체 오브젝트 경로를 사용하여 해당 에셋의 FAssetData를 조회한다.
- GetAllAssets(OutAssetData): 프로젝트 내 모든 에셋의 FAssetData 목록을 반환한다. 대규모 프로젝트에서는 성능에 유의해야 한다.
- AssetName: 에셋의 이름 (예: SM_MyMesh)
- PackageName: 에셋이 포함된 패키지의 이름 (예: /Game/Meshes/SM_MyMesh)
- PackagePath: 에셋이 위치한 패키지의 경로 (예: /Game/Meshes)
- AssetClass: 에셋의 클래스 이름 (FName, 예: StaticMesh)
- TagsAndValues: 에셋에 저장된 태그와 해당 값의 맵 (TMap<FName, FString>)
- FAssetData를 UObject 로 변환* FAssetData 객체가 실제로 가리키는 UObject 인스턴스를 얻기 위해서는 GetAsset() 함수를 호출한다. 이 함수는 해당 에셋이 메모리에 로드되어 있지 않다면 디스크로부터 로드하는 과정을 포함한다. 따라서 호출 시점에 로딩으로 인한 지연이 발생할 수 있다. IsAssetLoaded() 함수를 사용하면 해당 에셋이 현재 메모리에 로드되어 있는지 확인할 수 있다.
-
C++
// AssetDataList는 이전 단계에서 구한 TArray<FAssetData>라고 가정 for (const FAssetData& Asset : AssetDataList) { if (!Asset.IsAssetLoaded()) { UE_LOG(LogTemp, Log, TEXT("에셋 %s 로드 시도."), *Asset.AssetName.ToString()); } UObject* LoadedAsset = Asset.GetAsset(); // 필요시 로드 발생 if (LoadedAsset) { // 로드된 에셋 사용 } }
- 필터 만들기 (FARFilter 사용) IAssetRegistry::GetAssets() 함수에 FARFilter 구조체를 전달하여 특정 조건에 맞는 에셋 목록만 필터링하여 가져올 수 있다. FARFilter의 주요 멤버는 다음과 같다:
- PackageNames: 특정 패키지 이름 목록
- PackagePaths: 특정 패키지 경로 목록
- ClassNames: 특정 클래스 이름 목록 (FName 사용)
- RecursiveClassesExclusionSet: ClassNames와 함께 사용 시 제외할 파생 클래스 목록
- ObjectPaths: 특정 오브젝트 경로 목록
- TagsAndValues: 특정 태그와 값을 기준으로 필터링. (예: MyTag = "MyValue")
- bRecursivePaths: PackagePaths 검색 시 하위 경로 포함 여부
- bRecursiveClasses: ClassNames 검색 시 파생 클래스 포함 여부
-
C++
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry"); IAssetRegistry& Registry = AssetRegistryModule.Get(); TArray<FAssetData> FilteredAssetData; FARFilter Filter; Filter.ClassNames.Add(UStaticMesh::StaticClass()->GetFName()); // UStaticMesh 클래스 Filter.PackagePaths.Add(TEXT("/Game/Meshes")); // /Game/Meshes 경로 Filter.bRecursivePaths = true; // 하위 경로 포함 Registry.GetAssets(Filter, FilteredAssetData);
- 태그와 값 (Tags and Values) FAssetData의 TagsAndValues 멤버(FAssetDataTagMap, 즉 TMap<FName, FString>)는 에셋 파일 헤더에 저장된 특정 프로퍼티 값들의 컬렉션이다. 에셋 레지스트리는 UPROPERTY 선언 시 AssetRegistrySearchable 키워드가 지정된 프로퍼티의 값만을 이 맵에 자동으로 수집한다.UPROPERTY가 아닌 정보나 계산된 값을 에셋 레지스트리 태그로 노출시키려면, 해당 에셋의 UObject 파생 클래스에서 GetAssetRegistryTags() 가상 함수를 재정의(override)한다. 이 함수는 TArray<UObject::FAssetRegistryTag>를 채워 반환하며, 각 FAssetRegistryTag는 태그 이름, 값, 타입(문자열, 숫자, 불리언 등)을 가진다.
-
C++
// 예시: MyObject.h // class MyObject : public UObject // { // public: // virtual void GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const override; // int32 CustomData; // }; // 예시: MyObject.cpp // void MyObject::GetAssetRegistryTags(TArray<FAssetRegistryTag>& OutTags) const // { // Super::GetAssetRegistryTags(OutTags); // 부모 클래스 태그 포함 // OutTags.Add(UObject::FAssetRegistryTag(TEXT("CustomDataValue"), FString::FromInt(CustomData), UObject::FAssetRegistryTag::TT_Numerical)); // OutTags.Add(UObject::FAssetRegistryTag(TEXT("MyCustomTag"), TEXT("ImportantValue"), UObject::FAssetRegistryTag::TT_Alphabetical)); // }
-
C++
/** 이 텍스처를 샘플링할 때 사용할 텍스처 필터링 모드입니다. */ UPROPERTY(Category=Texture, EditAnywhere, AssetRegistrySearchable) // AssetRegistrySearchable 지정 TEnumAsByte<enum TextureFilter> Filter;
- 비동기 데이터 수집 및 델리게이트 에셋 레지스트리는 디스크의 .uasset 파일들을 비동기적으로 스캔하여 정보를 수집한다. 이 과정에서 발생하는 이벤트(애셋 추가, 제거, 이름 변경 등)에 대응하기 위해 델리게이트 콜백을 제공한다. IAssetRegistry 인터페이스를 통해 이러한 델리게이트에 함수를 등록하거나 해제할 수 있다.
- OnAssetAdded(): 새 에셋이 레지스트리에 추가될 때 호출된다.
- OnAssetRemoved(): 에셋이 레지스트리에서 제거될 때 호출된다.
- OnAssetRenamed(): 에셋의 이름이 변경될 때 호출된다.
- OnAssetUpdated(): 기존 에셋의 메타데이터가 업데이트될 때 호출된다 (별도 등록).
- OnFilesLoaded(): 초기 파일 스캔이 완료되었을 때 호출된다.
- OnFileLoadProgressUpdated(): 백그라운드 파일 스캔 진행 상황이 업데이트될 때 호출된다.
- IsLoadingAssets(): 현재 에셋 레지스트리가 파일 스캔 중이어서 전체 에셋 정보를 아직 모르는 경우 true를 반환한다. 초기 스캔 완료 후에도 파일 시스템 변경 감지로 인해 간헐적으로 true가 될 수 있다.
-
C++
// MyClass.h // class FMyClass // { // public: // FMyClass(); // ~FMyClass(); // private: // void OnAssetAdded_Handle(const FAssetData& NewAssetData); // FDelegateHandle OnAssetAddedDelegateHandle; // }; // MyClass.cpp // void FMyClass::FMyClass() // { // // 업데이트 감지를 위해 에셋 레지스트리 모듈 로드 // FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry"); // OnAssetAddedDelegateHandle = AssetRegistryModule.Get().OnAssetAdded().AddRaw(this, &FMyClass::OnAssetAdded_Handle); // } // FMyClass::~FMyClass() // { // if (FModuleManager::Get().IsModuleLoaded("AssetRegistry")) // 모듈 로드 여부 확인 // { // FAssetRegistryModule& AssetRegistryModule = FModuleManager::GetModuleChecked<FAssetRegistryModule>("AssetRegistry"); // AssetRegistryModule.Get().OnAssetAdded().Remove(OnAssetAddedDelegateHandle); // } // } // void FMyClass::OnAssetAdded_Handle(const FAssetData& NewAssetData) // { // // 애셋 레지스트리가 새 에셋을 발견 (생성 또는 디스크에서 발견). // // 이 콜백 함수 내의 코드는 빠르게 실행되어야 한다. // // 그렇지 않으면 전체 에셋 수집 프로세스가 지연될 수 있다. // UE_LOG(LogTemp, Log, TEXT("새 에셋 추가됨: %s"), *NewAssetData.PackageName.ToString()); // }
에셋 레지스트리 상태 및 캐싱
에셋 레지스트리는 에디터 시작 시 모든 유효한 에셋 경로를 스캔하여 초기 데이터베이스를 구축한다. 이 정보는 이후 에디터 세션에서의 빠른 접근을 위해 캐시될 수 있다 (보통 프로젝트의 Saved/ 폴더 내 또는 Derived Data Cache에 저장됨). 에디터 실행 중에도 파일 시스템 변경을 감지하여 레지스트리를 최신 상태로 유지한다.
런타임 에셋 레지스트리
에디터에서 사용되는 에셋 레지스트리와 별개로, 런타임 환경에서도 제한적인 형태의 에셋 레지스트리 사용이 가능하다. 런타임 레지스트리는 주로 쿠킹된 에셋에 대한 정보를 포함하며, 특정 조건에 맞는 에셋을 동적으로 검색하거나 DLC 콘텐츠 관리 등에 활용될 수 있다. 다만, 런타임에는 에디터만큼 방대한 메타데이터를 포함하지 않을 수 있으며, 프로젝트 설정에 따라 포함되는 정보가 달라진다.
'언리얼' 카테고리의 다른 글
2024언리얼페스타 2일차 프로그램세션 정리 (0) | 2025.05.13 |
---|---|
언리얼 MassFramework (1) | 2025.05.13 |
에셋 참조 (0) | 2025.05.13 |
코어 리디렉트 (0) | 2025.05.13 |
비동기 에셋 로딩 (Asynchronous Asset Loading) (0) | 2025.05.13 |