この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:T
更新日時:2026-06-11 07:07:02

タイトル: プライマリーデータアセットを活用する方法
SEOタイトル: UE5 Primary Data Asset の使い方|AssetManager・PrimaryAssetId・非同期ロード

この記事の要点
  • Primary Data Asset = AssetManager で管理される軽量参照可能な Data Asset
  • 通常の Data Asset との違いは直接の Hard Reference をしなくてもロード/参照できること
  • UPrimaryDataAsset を継承して作成、GetPrimaryAssetId() をオーバーライド
  • Project Settings → Asset Managerカテゴリ登録が必要
  • 実行時は UAssetManager::LoadPrimaryAssets()非同期ロード

Primary Data Asset とは

Primary Data Asset (PDA) は UE5 の Asset Manager システムと連携する Data Asset の特殊な形態です。通常の UDataAsset を Blueprint や C++ から直接参照するとHard Reference となりメモリに常駐しますが、PDA は PrimaryAssetId という軽量な ID で参照し、必要時に明示的にロードします。

通常の Data Asset との違い

項目通常の Data AssetPrimary Data Asset
基底クラスUDataAssetUPrimaryDataAsset
参照方法Hard Reference (TObjectPtr) / Soft ReferencePrimaryAssetId (FName + Type)
ロード参照されると自動ロード明示的に Load 呼び出し
Asset Manager 登録不要必要
用途少数の固定設定大量のアイテム / キャラ / モンスター定義
メモリ参照元が読まれると常駐必要なものだけロード

C++ で Primary Data Asset を定義

// ItemDataAsset.h
#pragma once

#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "ItemDataAsset.generated.h"

UCLASS(BlueprintType)
class MYGAME_API UItemDataAsset : public UPrimaryDataAsset
{
    GENERATED_BODY()

public:
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    FName ItemId;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    FText DisplayName;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    TSoftObjectPtr Icon;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    TSoftObjectPtr Mesh;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    int32 MaxStack = 99;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    float Weight = 1.0f;

    // ★ Asset Manager 用 ID を返す
    virtual FPrimaryAssetId GetPrimaryAssetId() const override
    {
        return FPrimaryAssetId(TEXT("Item"), GetFName());
    }
};

Asset Manager にカテゴリを登録

Project Settings → Game → Asset Manager → Primary Asset Types to Scan:

+ Primary Asset Type: Item
  Asset Base Class: UItemDataAsset
  Has Blueprint Classes: false
  Is Editor Only: false
  Directories:
    - /Game/Items
  Specific Assets: (空)
  Rules:
    Chunk Id: -1
    Cook Rule: Always Cook
    Apply Recursively: true

これにより /Game/Items 配下の UItemDataAsset 派生アセットが全て自動スキャンされ、FPrimaryAssetId(TEXT("Item"), AssetName) でアクセス可能になります。

実行時に非同期ロード

#include "Engine/AssetManager.h"

void AMyGameMode::LoadItem(FName ItemName)
{
    UAssetManager& AM = UAssetManager::Get();
    FPrimaryAssetId AssetId(TEXT("Item"), ItemName);

    // 非同期ロード開始
    FStreamableDelegate Delegate = FStreamableDelegate::CreateLambda([this, AssetId]()
    {
        UAssetManager& AM = UAssetManager::Get();
        UItemDataAsset* Item = Cast(AM.GetPrimaryAssetObject(AssetId));
        if (Item)
        {
            UE_LOG(LogTemp, Log, TEXT("Loaded: %s"), *Item->DisplayName.ToString());
            // 使用処理
        }
    });

    TArray Bundles;  // 必要なら "UI" などのバンドル名
    AM.LoadPrimaryAsset(AssetId, Bundles, Delegate);
}

複数の Primary Asset を一括ロード

void AMyGameMode::PreloadAllWeapons()
{
    UAssetManager& AM = UAssetManager::Get();

    TArray AssetIds;
    AM.GetPrimaryAssetIdList(TEXT("Item"), AssetIds);

    FStreamableDelegate Delegate = FStreamableDelegate::CreateLambda([]()
    {
        UE_LOG(LogTemp, Log, TEXT("Bulk load complete"));
    });

    AM.LoadPrimaryAssets(AssetIds, TArray(), Delegate);
}

Blueprint からの利用

Blueprint からも Primary Data Asset は扱えます:

  1. Content Browser で右クリック → Miscellaneous → Data Asset
  2. 親クラスとして ItemDataAsset を選択
  3. 個別のアイテム (Sword.uasset / Potion.uasset 等) を作成
  4. 各種パラメータを編集

Blueprint ノードで非同期ロード

Async Load Primary Asset (ノード)
  Asset:  Primary Asset Id (Item.Sword)
  Bundles: (empty)
  On Loaded → Cast to ItemDataAsset → 使用

サンプル: アイテム図鑑システム

// ItemDatabase.h
UCLASS()
class UItemDatabase : public UGameInstanceSubsystem
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable)
    void GetAllItems(TArray& OutIds)
    {
        UAssetManager::Get().GetPrimaryAssetIdList(TEXT("Item"), OutIds);
    }

    UFUNCTION(BlueprintCallable)
    void LoadItemAsync(FPrimaryAssetId Id, const FOnItemLoaded& Callback)
    {
        FStreamableDelegate Delegate = FStreamableDelegate::CreateLambda([Id, Callback]()
        {
            UItemDataAsset* Asset = Cast(
                UAssetManager::Get().GetPrimaryAssetObject(Id));
            Callback.ExecuteIfBound(Asset);
        });
        UAssetManager::Get().LoadPrimaryAsset(Id, TArray(), Delegate);
    }
};

Cook ルール

Cook Rule動作
Always Cook常にビルドに含める
Development Cook開発ビルドのみ
Never Cookビルドに含めない(デバッグ用)
Unknown他から参照された場合のみ

Asset Bundle で部分ロード

UAssetBundleData でテクスチャだけ先読み、メッシュは後でロードのような段階的読み込みが可能:

// AssetBundles メタタグで分類
UPROPERTY(EditAnywhere, AssetBundles="UI")
TSoftObjectPtr Icon;        // UI バンドル

UPROPERTY(EditAnywhere, AssetBundles="World")
TSoftObjectPtr Mesh;       // World バンドル

// ロード時に「UI」バンドルのみ
TArray Bundles = { TEXT("UI") };
AM.LoadPrimaryAsset(AssetId, Bundles, Delegate);

FAQ

Q: なぜ通常の DataAsset ではなく Primary Data Asset を使う?
A: アイテム数百〜数千の RPG / カードゲームでは、全てを Hard Reference にするとメモリと起動時間が爆発します。PDA で必要なものだけロードしましょう。

Q: Asset Manager で見つからない
A: Project Settings の Asset Manager 設定で Directories が正しいか、Cook Rule が Never Cook になっていないか確認。UAssetManager::Get().ScanPathsSynchronous で手動スキャンも可能。

Q: GetPrimaryAssetId は省略できる?
A: Asset Manager の設定で Asset Base Class が一致すれば自動的に FPrimaryAssetId(ClassName, AssetName) が割り当てられます。明示的にオーバーライドした方が制御しやすい。