ぼっちプログラマのメモ

UE4とかUE5とかについて書いたり書かなかったり。

【UE5】自作AnimNodeが持つプロパティのカテゴリーの表示順を変える方法

はじめに

この記事を見る方の大半はご存知の通り、UPROPERTY にて Category を設定すると

USTRUCT(BlueprintType)
struct KAWAIIPHYSICS_API FAnimNode_KawaiiPhysics : public FAnimNode_SkeletalControlBase
{
    GENERATED_USTRUCT_BODY()

public:

    UPROPERTY(EditAnywhere, Category = "Bones")
    FBoneReference RootBone;

下図のようにプロパティがカテゴリー単位でまとまって表示されます。

しかし、AnimNodeの一番頭にあるプロパティにも関わらず、 Functions・TagのようなAnimNode標準のカテゴリなどが先に表示されたりしています。また、カテゴリーをいい感じに並べるためには、 C++上での宣言の順序に気をつける必要が出てきます。

…めんどくさい!プロパティの順序は制御できるのにカテゴリーはなんで!?

【UE4】UPROPERTYのmetaを使ってプロパティの表示順を調整する方法について - ぼっちプログラマのメモ

と長年頭抱えてたのですが、実は簡単にカテゴリーの並び順を制御する方法がありました。

カテゴリーの表示順を変更する方法

自作ノードのAnimGraphNodeにて CustomizeDetails 関数を override し、下記のようにDetailBuilder.EditCategory("CATEGORY NAME").SetSortOrder()から表示順を変更することができます。

void UAnimGraphNode_KawaiiPhysics::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
    Super::CustomizeDetails(DetailBuilder);

    CustomizeDetailTools(DetailBuilder);
    CustomizeDetailDebugVisualizations(DetailBuilder);

    // Force order of details panel catagories - Must set order for all of them as any that are edited automatically move to the top.
    {
        uint32 SortOrder = 0;

        // Tools, Debug
        DetailBuilder.EditCategory("Kawaii Physics Tools").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("Debug Visualization").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("Functions").SetSortOrder(SortOrder++);

        // Basic
        DetailBuilder.EditCategory("Bones").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("Physics Settings").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("Physics Settings Advanced").SetSortOrder(SortOrder++);

        // Limits
        DetailBuilder.EditCategory("Limits").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("Bone Constraint (Experimental)").SetSortOrder(SortOrder++);

        // Other
        DetailBuilder.EditCategory("World Collision").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("ExternalForce").SetSortOrder(SortOrder++);

        // AnimNode
        DetailBuilder.EditCategory("Tag").SetSortOrder(SortOrder++);
        DetailBuilder.EditCategory("Alpha").SetSortOrder(SortOrder++);
    }
}

ちなみに、この機能は AnimGraphNode限定のものではないので、詳細パネルを扱うIDetailCustomizationCustomizeDetailsなどでも使うことができます。

なお、今回のコードは UAnimGraphNode_AnimDynamics::CustomizeDetailsにおける実装を参考にしましたが…改めてエンジンコードを追ってみると、もう少しカッコいいコードを書きたい人はUAnimGraphNode_StrideWarping::CustomizeDetailsとか FLandscapeEditorDetails::CustomizeDetailsを参考にするといいかもです。

…急に自分のコードがダサく見えてきたので、早速FLandscapeEditorDetails::CustomizeDetailsを参考に…

auto CategorySorter = [](const TMap<FName, IDetailCategoryBuilder*>& Categories)
    {
        int32 Order = 0;
        auto SafeSetOrder = [&Categories, &Order](const FName& CategoryName)
        {
            if (IDetailCategoryBuilder* const* Builder = Categories.Find(CategoryName))
            {
                (*Builder)->SetSortOrder(Order++);
            }
        };

        // Tools, Debug
        SafeSetOrder(FName("Kawaii Physics Tools"));
        SafeSetOrder(FName("Debug Visualization"));
        SafeSetOrder(FName("Functions"));

        // Basic
        SafeSetOrder(FName("Bones"));
        SafeSetOrder(FName("Physics Settings"));
        SafeSetOrder(FName("Physics Settings Advanced"));

        // Limits
        SafeSetOrder(FName("Limits"));
        SafeSetOrder(FName("Bone Constraint (Experimental)"));

        // Other
        SafeSetOrder(FName("World Collision"));
        SafeSetOrder(FName("ExternalForce"));

        // AnimNode
        SafeSetOrder(FName("Tag"));
        SafeSetOrder(FName("Alpha"));
    };

    DetailBuilder.SortCategories(CategorySorter);

ヨシッ!

余談

CustomizeDetailsではカテゴリの並び替えだけでなく、ボタンを追加したりなど詳細パネルを色々カスタムすることができます。エンジンコードだと、 UAnimGraphNode_AnimDynamics::CustomizeDetailsが参考になると思います。あと、

Plugins/KawaiiPhysics/Source/KawaiiPhysicsEd/Private/AnimGraphNode_KawaiiPhysics.cpp とかね!

余談 その2

この記事を公開した数分後に↓の記事を見つけるなど…ま、まあ、大量にカテゴリが存在する場合は PrioritizeCategories はちょっとおつらいから…!(震え声

meta = (PrioritizeCategories = "カテゴリー名A カテゴリー名B")

【UE5/C++】カテゴリーの表示順を変更したい - あっぷあっぷブログ

おしまい