スケルタルメッシュやスケルトンの編集画面を開くと、ボーンの名前と階層構造は確認できるのですが、ボーンインデックスは確認できません。
見つからないので Editor Utility Widget(以下、EUW) でボーンインデックスビュワーを作りました。
動作環境
Unreal Engine 5.5 Preview, 5.5
Visual Studio 2022
Windows 11 Home
スケルタルメッシュを選択すると、そのスケルタルメッシュが参照しているスケルトンのボーンインデックスとボーンの名前を表示するだけの EUW です。
ウィジェットの構成は以下の画像のようになっています。
※画像をタップまたはクリックすると拡大表示します。
スケルタルメッシュを選択する部分(上記画像の赤枠部分)は、過去の記事に掲載した Asset Selector Widget を使います。
詳しい内容は以下の記事をご確認ください。
上記画像の青枠部分には Editor Utility Button を設置していますが、押しても何もしません。
複数のボタンを並べて、タブのように切り替えるつもりでボタンにしたのですが、結局使いませんでした。
なので、テキストでも問題ないです。
緑枠部分にボーンインデックスとボーン名を表示します。
ScrollBox の中に VerticalBox を配置して、リストビューのように使います。
リストビューは対応がめんどくさいので使ってません。
ボーンインデックスと呼ばれるものは、以下の3種類あるようです。
- スケルトン用
- メッシュ用
- コンパクトポーズ用
ここではスケルトン用のボーンインデックスだけ必要なので、残りの2つには対応しません(取り方も不明)。
// Copyright dokuro.moe Rights Reserved. // BoneIndexFunctions.h #pragma once #include "CoreMinimal.h" #include "Runtime/Engine/Classes/Kismet/BlueprintFunctionLibrary.h" #include "BoneIndexFunctions.generated.h" USTRUCT(BlueprintType) struct モジュール名_API FBoneIndexParams { GENERATED_BODY() UPROPERTY(BlueprintReadWrite) int32 Index{-1}; UPROPERTY(BlueprintReadWrite) FName Name; }; UCLASS(BlueprintType) class モジュール名_API UBoneIndexViewerFunctionLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: UFUNCTION(BlueprintCallable) static TArray<FBoneIndexParams> GetSkeletonBoneIndices(USkeletalMesh* InSkeletalMesh); };
// Copyright dokuro.moe Rights Reserved. #include "BoneIndexFunctions.h" //static TArray<FBoneIndexParams> UBoneIndexViewerFunctionLibrary::GetSkeletonBoneIndices(USkeletalMesh* InSkeletalMesh) { TArray<FBoneIndexParams> ParamsArray; if (!IsValid(InSkeletalMesh)) { return ParamsArray; } const FReferenceSkeleton& Skeleton = InSkeletalMesh->GetRefSkeleton(); const int32 BoneNum = Skeleton.GetNum(); ParamsArray.Reserve(BoneNum); for (int32 BoneIndex = 0; BoneIndex < BoneNum; BoneIndex++) { const FName BoneName = Skeleton.GetBoneName(BoneIndex); FBoneIndexParams Params; Params.Index = BoneIndex; Params.Name = BoneName; ParamsArray.Add(Params); } return ParamsArray; }
ブループリントでアクセスできるよう、親が UBlueprintFunctionLibrary のクラスに static な UFUNCTION を追加しています。
この関数は、スケルタルメッシュのポインタを渡すと、スケルトン用のボーンインデックスと、ボーンインデックスに対応するボーン名を構造体の配列(TArray)に格納して返してくれます。
スケルタルメッシュからスケルトンのボーン情報にアクセスするには、USkeletalMesh::GetRefSkeleton() を使います。
プロジェクト名が「Test」なら、TEST_API
Test プロジェクトのエディタモジュールなら、TESTEDITOR_API
BoneIndex プラグインなら BONEINDEX_API など…。
モジュール名_API について詳しく知りたい方は、こちらの記事をご覧ください。
上図の赤枠で囲ったノード(Get Skeleton Bone Indices)が、前項のコードで追加した UFUNCTION です。
スケルタルメッシュのポインタを渡してあげるだけですが、スケルタルメッシュのポインタを取得するために、いくつかのプロセスが必要になります。
こちらの記事で作成した AssetSelectorWidget を使って、プロジェクト内にあるスケルタルメッシュを選択すると、そのパスが Asset Path に入ります。
パスは、コンテンツブラウザでスケルタルメッシュのサムネイルを右クリックして「パッケージパスをコピー」で取得できます。
Asset Path を使って、Load Asset でスケルタルメッシュをメモリに読み込み、読み込んだデータのポインタを Cast To SkeletalMesh でキャストします。
SkeletalMesh にキャストしないと、Get Skeleton Bone Indices ノードに渡せません。
Get Skeleton Bone Indices ノードからボーン情報の配列を受け取ります。
その配列に対して For Each Loop で配列要素をひとつずつ処理して、ボーンインデックスとボーン名のリストを作成しています。
ボーンインデックスとボーン名の一覧を表示する部分にリストビューは使っていません。
VerticalBox にリスト項目を追加するだけで済ませたかったので、Scroll Box の子に VerticalBox を設定しているだけです。
リストに表示する項目は別の EUW で作っています。
リスト項目は別の EUW で作ります。
ウィジェットはこんな感じ。
※画像をタップまたはクリックすると拡大表示します。
外部からウィジェットのテキストを変更したり、表示サイズを変更するブループリント関数をいくつか追加しています。
大したことはやっていないので、関数の中身は割愛します。
元の EUW に戻ります。
上記は「追加したコードをブループリントで使う」で示した図です。
これには For Each Loop から先の処理が入っていませんが、その処理を以下に示します。
リスト項目の EUW を Create EUW … Widget ノードで生成したら(赤枠部分)、その EUW が持っているブループリント関数を使って、リスト項目に表示するテキストや表示サイズを設定し(緑枠部分)(「リスト項目のブループリント」で図示した関数群です)、最後に VerticalBox に AddChild (青枠部分)しています。
リストビューを使う場合は、親クラスは UObject にすればいいのか、UUserWidget にすればいいのかで迷ってネット検索して調べたり、インターフェースを登録しなきゃならなかったり、リストビューのエントリー周りの作り方や設定が面倒なので、ScrollBox と VerticalBox で対応しました。
興味がある方のみ以下のスポイラーをクリックして内容をご確認ください。
ダウンロードしたら BoneIndexViewer フォルダをプロジェクトの Plugins フォルダに放り込めば使えると思います。
README.md と LICENSE は動作確認には不要ですので、削除して構いません。
UE 5.5 Preview か UE 5.5 でないとビルドが通らないので気を付けてください。
Asset Selector Widget プラグイン の EUW とソースコードを流用しています。
AssetSelectorWidget プラグインを使っている場合は無効にしてから、このプラグインを導入してください。