-
[UE5] AssetManagerUE5/Lyra Clone Coding 2025. 1. 21. 00:05
AssetManager란?
UAssetManager는 Unreal Engine에서 에셋(Assets)을 효율적으로 로드 및 관리하는 시스템이다.
📌 주요 기능:
✅ 게임 내 특정 리소스를 동적으로 로드 & 언로드 (메모리 최적화)
✅ Primary Asset Type을 기반으로 에셋을 그룹화하여 관리
✅ 비동기(Async) 로딩 지원 → 게임 실행 중 성능 최적화 가능
✅ 패키징과 쿠킹을 최적화하여 빌드 크기를 줄일 수 있음즉, UAssetManager는 게임이 실행될 때 필요한 에셋만 로드하여 메모리 사용을 최적화하고, 필요하지 않은 리소스를 제거하여 성능을 최적화하는 시스템이다.
AssetManager의 필요성
AssetManager를 사요하지 않고 ConstructorHelpers::FObjectFinder를 통해 하드코딩된 경로로 Asset을 불러오면 아래와 같이 수백, 수천개의 Asset의 경로를 하드코딩을 통해 불러와야한다.
static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/..."));
심지어 경로가 변경된다면..? (끔찍)
AssetManager는 Singleton
UAssetManager는 전역적으로 하나의 인스턴스만 존재하며, UAssetManager::Get()을 사용하여 어디서든 접근할 수 있다.
싱글톤인 이유 :
- UAssetManager는 Unreal Engine 전체에서 공유되는 단일 인스턴스여야 함.
- 여러 개의 AssetManager가 존재하면 에셋 로드 및 캐시 관리가 충돌할 수 있음.
- 싱글톤 패턴을 통해 메모리 및 성능을 최적화하고 동기화 문제를 방지함.
UZSAssetManager& UZSAssetManager::Get() { check(GEngine); // UZSAssetManager override GEngine's AssetManager if (UZSAssetManager* Singleton = Cast<UZSAssetManager>(GEngine->AssetManager)) { return *Singleton; } UE_LOG(LogZS, Fatal, TEXT("Invalid AssetManagerClassname in DefaultEngine.ini(project settings); it must be ZSAssetManager")); // never return because of Fatal crash, but use to compile return *NewObject<UZSAssetManager>(); }
SynchronousLoadAsset
UObject* UZSAssetManager::SynchronousLoadAsset(const FSoftObjectPath& AssetPath) { if (AssetPath.IsValid()) { TUniquePtr<FScopeLogTime> LogTimePtr; if (ShouldLogAssetLoads()) { LogTimePtr = MakeUnique<FScopeLogTime>(*FString::Printf(TEXT("synchronous loaded assets [%s]"), *AssetPath.ToString()), nullptr, FScopeLogTime::ScopeLog_Seconds); } if (UAssetManager::IsValid()) { return UAssetManager::GetStreamableManager().LoadSynchronous(AssetPath); } return AssetPath.TryLoad(); } return nullptr; }
- AssetManager가 Asset을 불러오는데 시간을 얼마나 소비하는지 로깅. 너무 오래걸리면 동기 로딩 하면 안되니까 따로 빼야함.
- AssetManager가 있으면, StreamableManager를 통해 정적 로딩
- AssetManager가 없으면, StaticLoadObject를 통해 로딩(TryLoad). 근데 캐싱되어있으면 거기서 가져옴. 매우매우 느리기 때문에 최악의 경우임(AssetManager에 등록안되어 있는..)
GetAsset
template<typename AssetType> AssetType* UZSAssetManager::GetAsset(const TSoftObjectPtr<AssetType>& AssetPointer, bool bKeepInMemory) { AssetType* LoadedAsset = nullptr; const FSoftObjectPath& AssetPath = AssetPointer.ToSoftObjectPath(); if (AssetPath.IsValid()) { LoadedAsset = AssetPointer.Get(); if (!LoadedAsset) { LoadedAsset = Cast<AssetType>(SynchronousLoadAsset(AssetPath)); ensureAlwaysMsgf(LoadedAsset, TEXT("Failed to load asset [%s]"), *AssetPointer.ToString()); } if (LoadedAsset && bKeepInMemory) { Get().AddLoadedAsset(Cast<UObject>(LoadedAsset)); } } return LoadedAsset; }
- TSoftObjectPtr에서 에셋의 경로(FSoftObjectPath)를 가져옴.
- 이미 로드된 에셋이 있는지 확인 (Get() 호출).
- 로드되지 않았다면 SynchronousLoadAsset()을 호출하여 동기적으로 로드.
- 로드 실패 시 ensureAlwaysMsgf()를 통해 오류 확인.
- bKeepInMemory가 true이면, AddLoadedAsset()을 호출하여 메모리에 유지. 에셋을 GC에 의해 자동으로 삭제되지 않도록 보장.
AddLoadedAsset
void UZSAssetManager::AddLoadedAsset(const UObject* Asset) { if (ensureAlways(Asset)) { FScopeLock Lock(&SyncObject); LoadedAssets.Add(Asset); } }
- FScopeLock Lock(&SyncObject); → 멀티스레딩 환경에서도 안전하게 관리
- LoadedAssets.Add(Asset); → 에셋을 LoadedAssets 목록에 추가하여 관리
'UE5 > Lyra Clone Coding' 카테고리의 다른 글
[UE5] Camera (0) 2025.02.05 [UE5] PawnExtension(2) - 구성 요소 분석 (0) 2025.02.03 [UE5] PawnExtension (0) 2025.01.31 [UE5] Experience (0) 2025.01.23 [UE5] AssetManager Scan (1) 2025.01.21