ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [UE5] AssetManager
    UE5/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()을 사용하여 어디서든 접근할 수 있다.

    싱글톤인 이유 : 

    1. UAssetManager는 Unreal Engine 전체에서 공유되는 단일 인스턴스여야 함.
    2. 여러 개의 AssetManager가 존재하면 에셋 로드 및 캐시 관리가 충돌할 수 있음.
    3. 싱글톤 패턴을 통해 메모리 및 성능을 최적화하고 동기화 문제를 방지함.
    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
Designed by Tistory.