콘텐츠로 이동

UE5 Asset Manager와 Primary Asset 관리

Asset Manager는 Primary Asset(게임의 주요 데이터 에셋)을 중앙에서 등록·로드·언로드하는 시스템입니다. Addressables와 달리 UE 내장 솔루션으로 쿠킹과 청크 시스템에 직접 통합됩니다.

UCLASS()
class UWeaponDefinition : public UPrimaryDataAsset {
GENERATED_BODY()
public:
// Primary Asset Type/Name은 GetPrimaryAssetId()로 결정
virtual FPrimaryAssetId GetPrimaryAssetId() const override {
return FPrimaryAssetId(TEXT("WeaponDef"), GetFName());
}
UPROPERTY(EditAnywhere) FText DisplayName;
UPROPERTY(EditAnywhere) float BaseDamage;
UPROPERTY(EditAnywhere) TSoftObjectPtr<USkeletalMesh> Mesh;
UPROPERTY(EditAnywhere) TSoftClassPtr<UGameplayAbility> AttackAbility;
};
[/Script/Engine.AssetManagerSettings]
+PrimaryAssetTypesToScan=(
PrimaryAssetType="WeaponDef",
AssetBaseClass=/Script/MyGame.WeaponDefinition,
bHasBlueprintClasses=False,
bIsEditorOnly=False,
Directories=((Path="/Game/Data/Weapons")),
Rules=(Priority=1, ChunkId=0, CookRule=AlwaysCook)
)
void UWeaponManager::LoadWeapon(FPrimaryAssetId WeaponId) {
UAssetManager& AM = UAssetManager::Get();
// 로드 핸들 요청
TArray<FName> Bundles; // 빈 배열 = 기본 번들
FStreamableDelegate Delegate = FStreamableDelegate::CreateUObject(
this, &UWeaponManager::OnWeaponLoaded, WeaponId);
AM.LoadPrimaryAsset(WeaponId, Bundles, Delegate);
}
void UWeaponManager::OnWeaponLoaded(FPrimaryAssetId WeaponId) {
UWeaponDefinition* Def = Cast<UWeaponDefinition>(
UAssetManager::Get().GetPrimaryAssetObject(WeaponId));
if (Def) SpawnWeapon(Def);
}

번들은 Primary Asset에 연결된 Secondary Asset을 그룹화합니다.

// WeaponDefinition에 번들 정보 추가
virtual void GetAssetBundleData(FAssetBundleData& AssetBundle) const override {
// "Equipped" 번들: 장착 시 로드
AssetBundle.AddBundleAsset(TEXT("Equipped"), Mesh.ToSoftObjectPath());
AssetBundle.AddBundleAsset(TEXT("Equipped"), AttackAbility.ToSoftObjectPath());
// "UI" 번들: 인벤토리 표시용
AssetBundle.AddBundleAsset(TEXT("UI"), Icon.ToSoftObjectPath());
}
// 장착 시 Equipped 번들만 로드
AM.LoadPrimaryAsset(WeaponId, { TEXT("Equipped") }, OnLoadedDelegate);
// 등록된 모든 WeaponDef 에셋 목록
TArray<FPrimaryAssetId> WeaponIds;
UAssetManager::Get().GetPrimaryAssetIdList(TEXT("WeaponDef"), WeaponIds);
for (const FPrimaryAssetId& Id : WeaponIds) {
FAssetData Data;
UAssetManager::Get().GetPrimaryAssetData(Id, Data);
UE_LOG(LogTemp, Log, TEXT("Weapon: %s"), *Data.AssetName.ToString());
}
// 런타임에 청크 할당 변경
FPrimaryAssetRules Rules;
Rules.ChunkId = 1; // DLC 청크
Rules.CookRule = EPrimaryAssetCookRule::AlwaysCook;
Rules.Priority = 1;
UAssetManager::Get().SetPrimaryAssetRules(WeaponId, Rules);
// 더 이상 필요 없는 에셋 언로드
UAssetManager::Get().UnloadPrimaryAsset(WeaponId);
// 여러 에셋 일괄 언로드
UAssetManager::Get().UnloadPrimaryAssets(WeaponIds);
  • UPrimaryDataAsset을 상속해 GetPrimaryAssetId() 구현
  • DefaultGame.ini에 스캔 경로와 쿠킹 규칙 등록
  • 번들로 에셋 그룹화 — 필요한 번들만 로드해 메모리 절약
  • LoadPrimaryAsset 비동기 콜백으로 로드 완료 시 처리
  • DLC/패치는 ChunkId로 분리, 런타임 규칙 변경 가능