アセット レジストリ は、エディタのロード時にアンロードされたアセットについての情報を非同期式に収集するエディタのサブシステムです。 情報はメモリに格納されるので、エディタによる情報の読み込みなしにアセットリストが作成できます。 この情報は信頼できるものであり、アセットはメモリ内、またファイルはディスク上でそれぞれ変更されるため、常に自動更新されています。 コンテンツ ブラウザ がこのシステムを主に使用しますが、エディタ コードでも使用される場合があります。
アセット リストの取得
クラス毎にアセットリストを作成するには、単に Asset Registry モジュールをロードして、 Module.Get().GetAssetsByClass()
を呼び出します。
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FAssetData> AssetData;
const UClass* Class = UStaticMesh::StaticClass();
AssetRegistryModule.Get().GetAssetsByClass(Class->GetFName(), AssetData);
FAssetData
オブジェクトのリストを返します。このリストはロードまたはアンロードされたアセットを説明します。
FAssetData
オブジェクトは、ロード前に確定されるアセット情報を格納します。
オブジェクトのメンバーと各説明は以下となります。
メンバー | 説明 |
---|---|
FName ObjectPath |
「Package.GroupNames.AssetName」形式のアセットのオブジェクトパスです。 |
FName PackageName |
アセットが見つかったパッケージの名前です。 |
FName PackageName |
アセットが見つかったパッケージへのパスです。 |
FName GroupNames |
アセットが見つかったグループ名の「 '.' 」区切りリストです。グループが無い場合は「 NAME_None 」となります。 |
FName PackageName |
パッケージやグループが無いアセット名です。 |
FName AssetClass |
アセットのクラス名です。 |
TMap<FName, FString> TagsAndValues |
AssetRegistrySearchable とマークされたプロパティのマップ値です。詳細は「タグと値」を参照してください。 |
以下のいずれかの関数を呼び出すと、他の基準でリストを生成することができます。
関数 | 説明 |
---|---|
GetAssetsByPackageName() |
ある特定のパッケージからアセットのリストを返します。 |
GetAssetsByPath() |
指定パスにあるアセットのリストを返します。 |
GetAssetByObjectPath() |
ある特定のコレクションに属するアセットのリストを返します。 |
GetAssetByObjectPath() |
指定された一連のタグと値を含んだアセットのリストを返します。 |
GetAllAssets() |
全てのアセットのリストを返します。この関数は処理が遅くなります。 |
複数の基準でアセットのリストを生成するには、 GetAssets()
を使用して、 「フィルタを作成する」セクションで説明されている FARFilter
構造体を定義します。
FAssetData を UObject* へ変換する
FAssetData
オブジェクトには、
FAssetData
を意味する UObject*
を返す GetAsset()
という名前の関数があります。必要に応じてアセットを読み込んで、その後アセットを返します。
アセットがロード済みであることのみをチェックしたい場合、代わりに IsAssetLoaded()
を使用します。
フィルタを作成する
複数の基準でフィルタリングされたアセットのリストを作成する GetAssets()
を呼び出すと、
FARFilter
が提供されます。フィルタは以下の複数のコンポーネントから構成されます。
- PackageName
- PackagePath
- Collection
- Class
- Tags/Value pairs
コンポーネントは複数の要素で構成される場合があります。全ての コンポーネントが満たされた場合、アセットはフィルタをパスします。 コンポーネントを満たすには、要素の いずれか がアセットと合致しなくてはいけません。
例えば、パスが「/Game/Meshes/BeachBall」であるスタティック メッシュ アセットが存在する場合は以下になります。
- フィルタに PackagePath
/Game/Meshes
のみが含まれる場合、アセットはパスします。1 つの要素のみを持つコンポーネントは 1 つしかありません。 - フィルタに PackagePath
/Game/Meshes
と Class のUParticleSystem
かつUStaticMesh
が含まれる場合アセットはパスします。最初に 1 つの要素、次に 2 つの要素を持つ 2 つのコンポーネントがあります。 - フィルタに PackagePath
/Game/Meshes
とクラスのUParticleSystem
.のみ 含まれると、アセットは失敗します。フィルタはそれぞれが 1 つの要素を持つ 2 つのコンポーネントを使用します。 フィルタに PackagePath の/Game/NotMeshes
と Class のUStaticMesh
が含まれる場合アセットは失敗します。このフィルタもそれぞれが 1 つの要素を持つ 2 つのコンポーネントを使用します。
2 つコンポーネント、 Class と PackagePath を使用したフィルタの例です。
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
TArray<FAssetData> AssetData;
FARFilter Filter;
Filter.Classes.Add(UStaticMesh::StaticClass());
Filter.PackagePaths.Add("/Game/Meshes");
TArray<FAssetData> AssetData;
タグと値
アセット レジストリから返される FAssetData
オブジェクトは、TagsAndValues
と呼ばれる名前と値マップを含みます。
これは FAssetData
が示すアセットのプロパティ名と関連した値のリストです。
この情報は、アセットを格納する「UAsset」ファイルのヘッダにアセットが保存格納された時に収集されます。
アセット レジストリはこのヘッダを読み込み、適宜 TagsAndValues
マップへ書き込みます。
アセット レジストリは AssetRegistrySearchable
の UPROPERTY()
フラグでマークされたプロパティのみを収集します。
例 (UTexture
から)
/** このテクスチャをサンプリングするときに使用するテクスチャ フィルタリング モードです。 */
UPROPERTY(Category=Texture, AssetRegistrySearchable)
TEnumAsByte<enum TextureFilter> Filter;
このフラグが UTexture
の 'Filter' プロパティに追加されると、その後保存される全ての UTextures は、 FAssetData
の TagsAndValues
マップに入力があります。 TagsAndValues
マップのキーは Filter
で、その値は "TF_Linear"
等の文字列を示す列挙型変数値です。
アセット レジストリによってプロパティが検出される前に、再度アセットを保存する必要があります。
アセット レジストリを使用して、Uproperty に直接関する情報を検索をしたい場合は、 アセットのクラスに仮想関数を実装することが出来ます。GetAssetRegistryTags() は手動でキー/値ペアを TagsAndValues マップに追加します。GetAssetRegistryTags は UObject から継承されます。
非同期式なデータ収集
アセット レジストリは「UAsset」を非同期に読み込むため、要求時には全アセットが全てそろったリストがない場合があります。 ご使用のエディタコードに完全なリストが必要な場合、アセットの検出 / 作成、名前変更または削除時に、 アセット レジストリがデリゲートをコールバックします。アセット レジストリによる初回検索終了時用のデリゲートは、 多くのシステムにとって実用的です。
アセット レジストリ モジュールをロードしてこれらのデリゲートに登録し、IAssetRegistry
に用意された関数を使用することも出来ます。
/** レジストリにアセットが追加されたときのコールバックを登録/解除する */
virtual FAssetAddedEvent& OnAssetAdded() = 0;
/** アセットがレジストリから削除されたときのコールバックを登録/解除する */
virtual FAssetRemovedEvent& OnAssetRemoved() = 0;
/** アセットがレジストリでリネームされたときのコールバックを登録/解除する */
virtual FAssetRenamedEvent& OnAssetRenamed() = 0;
/** アセットレジストリのファイル読み込みが完了したときのコールバックを登録/解除する */
virtual FFilesLoadedEvent& OnFilesLoaded() = 0;
/** バックグラウンドのファイルロードの進捗状況を更新するためのコールバックを登録/解除する */
virtual FFileLoadProgressUpdatedEvent& OnFileLoadProgressUpdated() = 0;
/** アセットレジストリが現在ファイルをロード中で、まだすべてのアセットを把握していない場合は true を返す */
virtual bool IsLoadingAssets() = 0;
例:
void FMyClass::FMyClass()
{
// アセット レジストリ モジュールをロードして更新をリッスンする
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
AssetRegistryModule.Get().OnAssetAdded().AddRaw( this, &FMyClass::OnAssetAdded );
}
FMyClass::~FMyClass()
{
// デリゲートの登録を解除するために、アセット レジストリ モジュールをロードする
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
AssetRegistryModule.Get().OnAssetAdded().RemoveAll( this );
}
void FMyClass::OnAssetAdded(const FAssetData& AssetData)
{
// アセットレジストリによってアセットが発見されました。
// これは、作成されたばかりか、最近ディスク上で発見されたことを意味します。
// この関数内のコードが高速であることを確認してください、または収集プロセスを遅くします。
}
アセット レジストリをコマンドレットで使用することも出来ますが、
その場合情報が同期で収集されます。情報収集が終了するまで、 LoadModule()
コールはブロックされます。
ユーザーのコードが非同期的なアセットの検出を待ったり、 Slate UI フロントエンドを持つ場合、
進捗をユーザーに伝えるため SAssetDiscoveryIndicator
ウィジットをコードに格納すべきです。