改訂バージョン: Unreal Engine 4.21 |
Meshなどの編集画面に「AssetUserData」という項目があるのをみなさんはご存知でしょうか?(私は知りませんでした)

配列で所持することができ設定するときはクラスを指定してあげるのですが最初は何もなく指定することができません。また普段は表示されておらず隠れていますが検索、もしくは三角のアイコンを押すことで現れるこの「AssetUserData」について今日はご紹介したいと思います。
○はじめに
確認したのはEngine Version 4.18.3になります。
○UAssetUserDataについて
まずはドキュメントを見てみます
○ドキュメント
https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/UAssetUserData/
Google翻訳におまかせでいくと
Unrealのアセットオブジェクトにカスタムデータを格納するためにサブクラス化できるオブジェクト。
??
らしいです。
機能としてはUAssetUserDataを継承してアセット自体にデータを持たすことができるようにするものみたいです。
AssetUserDataを所持できるクラスはインターフェイスのIInterface_AssetUserDataを使用しています。
ただこのインターフェイスはいずれもC++でのみ使用できBlueprintからアクセスできるものはないようです。
IInterface_AssetUserDataは全部で6つ定義があります。
AddAssetUserData |
UAssetUserDataクラス指定で追加する(クラスの重複はしないようにチェックしてる) |
GetAssetUserDataOfClass |
クラス指定で1つのUAssetUserDataを取得する |
GetAssetUserDataArray |
すべてのUAssetUserDataを配列で返す |
RemoveUserDataOfClass |
UAssetUserDataクラス指定で削除する |
GetAssetUserData |
GetAssetUserDataOfClassでCastするテンプレート関数 |
GetAssetUserDataChecked |
GetAssetUserDataOfClassでCastCheckedするテンプレート関数 |
となっています。同じクラスのインスタンスは基本持たないような方針のようです。
4.18.3時点でこのIInterface_AssetUserDataを使用してAssetUserDataを所持してるのは
全部で9つありそのうち4つがエディターから設定できるようになっています。いずれも配列でUAssetUserDataを所持しています。
○C++のみアクセス可能なオブジェクト
UActorComponent
AWorldSettings
ULevel
UGeometryCache
USkeleton (EditAnywhereついてるがエディター上から設定する箇所がわからなかった)
○エディターから設定できるオブジェクト
USkeletalMesh
UStaticMesh
UTexture
UAnimationAsset(AnimSequenceやAnimMontageの親になるクラス)
○UAssetUserDataをエディター上から設定できる場所
⇓ SkeletalMeshエディター画面

⇓ Animationエディター画面

⇓ StaticMeshエディター画面

⇓ Textureエディター画面

○UAssetUserDataを継承して使用する
UAssetUserDataから直接Blueprint継承することはできません。なのでBlueprint定義のAssetUserDataを作成する場合は
|
#pragma once #include "CoreMinimal.h" #include "Engine/AssetUserData.h" #include "MyAssetUserData.generated.h" UCLASS(Blueprintable) class BLOGTEST421_API UMyAssetUserData : public UAssetUserData { GENERATED_BODY() }; |
のように1度UAssetUserDataを継承したC++クラスを作成すればこれを継承させることでBlueprintクラスは作成できます。
試しに「BP-TestAsset」というクラスを作成しました。

このクラスをAssetUserDataに設定してあげると

以下のようにエディター画面で定義した変数が表示されアセット単位でパラメータを設定することができます。
また単なるクラスなので関数、カスタムイベントも追加可能
ただDelayなどレイテントノードは使用できないです。
○UAssetUserDataをBlueprintで取得する
見た限り現状Blueprintから取得する方法はなかったので以下のようなものを作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#pragma once #include "CoreMinimal.h" #include "Kismet/BlueprintFunctionLibrary.h" #include "MyBlueprintFunctionLibrary.generated.h" UCLASS() class BLOGTEST421_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() /** * 対象のオブジェクトがもつAssetUserDataを取得する * @param UObject* TargetObject 対象となるオブジェクト * @param TSubclassOf AssetUserDataClass 指定のクラス名 * @param TArray<UAssetUserData*>& OutAssetUserData 取得したAssetUserDataの配列 */ UFUNCTION(BlueprintCallable, Category = "Utilities", meta = (DeterminesOutputType = "AssetUserDataClass", DynamicOutputParam = "OutAssetUserData")) static void GetAllAssetUserDataOfClass(UObject* TargetObject, TSubclassOf AssetUserDataClass, TArray& OutAssetUserData); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include "MyBlueprintFunctionLibrary.h" void UMyBlueprintFunctionLibrary::GetAllAssetUserDataOfClass(UObject * TargetObject, TSubclassOf AssetUserDataClass, TArray& OutAssetUserData) { OutAssetUserData.Reset(); IInterface_AssetUserData* Interface = Cast(TargetObject); if (Interface == nullptr) { return; } auto Array = (*Interface->GetAssetUserDataArray()); for (auto Data : Array) { if (Data != NULL && Data->IsA(AssetUserDataClass)) { OutAssetUserData.Add(Data); } } } |

IInterface_AssetUserDataを継承してあればどのオブジェクトでも指定のUAssetUserDataクラスを取得することができます。
○まとめ
- UAssetUserDataを継承してアセット自体にデータを持たすことができるようにするもの
- エディター上から設定できるのはSkeletalMesh、StaticMesh、Texture、AnimationAsset(AnimSequenceやAnimMontageの親になるクラス)の4つ
- 使用するときはC++ならアクセス可能、Blueprintからは取得する方法はないので自分で作成する必要はある