UE5 Common UI お試し ④ Action Bar

上記の続きです。

前回の Default Back Action で出てきた bIsBackActionDisplayedInActionBar について見ていきます。

void UCommonActivatableWidget::NativeConstruct()
{
    Super::NativeConstruct();

    if (bIsBackHandler)
    {
        FBindUIActionArgs BindArgs(ICommonInputModule::GetSettings().GetDefaultBackAction(), FSimpleDelegate::CreateUObject(this, &UCommonActivatableWidget::HandleBackAction));
        BindArgs.bDisplayInActionBar = bIsBackActionDisplayedInActionBar;

        DefaultBackActionHandle = RegisterUIActionBinding(BindArgs);
    }

    // 略
}

登録するアクションの bDisplayInActionBar に設定されています。

コード

Release blog20221027 · dany1468/UE_CommonUISample · GitHub

blog20221027 でタグを打ってあります。

RegisterUIActionBinding

前回の Default Back Action でアクションを登録する部分の内部です。RegisterUIActionBindingCommonActivatableWidget の親クラスの CommonUserWidget にあります。

FUIActionBindingHandle UCommonUserWidget::RegisterUIActionBinding(const FBindUIActionArgs& BindActionArgs)
{
    if (UCommonUIActionRouterBase* ActionRouter = UCommonUIActionRouterBase::Get(*this))
    {
        FBindUIActionArgs FinalBindActionArgs = BindActionArgs;
        if (bDisplayInActionBar && !BindActionArgs.bDisplayInActionBar)
        {
            FinalBindActionArgs.bDisplayInActionBar = true;
        }
        FUIActionBindingHandle BindingHandle = ActionRouter->RegisterUIActionBinding(*this, FinalBindActionArgs);
        ActionBindings.Add(BindingHandle);
        return BindingHandle;
    }

    return FUIActionBindingHandle();
}

まずは以下の if ブロックを確認します。

if (bDisplayInActionBar && !BindActionArgs.bDisplayInActionBar)
{
    FinalBindActionArgs.bDisplayInActionBar = true;
}

前回の Default Back Action の例でいうと、WBP_MenubIsBackActionDisplayedInActionBar が false でかつ、bDisplayInActionBar が true の場合に、最終的に登録するアクションの bDisplayInActionBar を true にするというものです。
つまり、Back Action として Action Bar への表示が false になっていても、WBP_Menu 自体の Action Bar 表示が有効であればそちらを優先するということのようです。

Action Bar

さて、当然ながらチェックを入れただけだと何も表示はされません。bDisplayInActionBar でコードを検索すると CommonBoundActionBar で利用されていることが分かります。

/**
 * A box populated with current actions available per CommonUI's Input Handler.
 */
UCLASS(Blueprintable, ClassGroup = UI, meta = (Category = "Common UI"))
class COMMONUI_API UCommonBoundActionBar : public UDynamicEntryBoxBase

上記の定義から UI で利用できるものとわかりました。確かに Widget の Designer からも確認できます。

これを以下のように WBP_Menu のボタンの右端に配置しました。ただ、これだとコンパイルエラーになります。

ActionButtonClass が必要とのメッセージが出たので確認します。

UPROPERTY(EditAnywhere, Category = EntryLayout)
TSubclassOf<UCommonBoundActionButton> ActionButtonClass;

確かに上記の定義がありました。続いて ActionButtonClass の型である UCommonBoundActionButton です。

UCLASS(Abstract, meta = (DisableNativeTick))
class COMMONUI_API UCommonBoundActionButton : public UCommonButtonBase

UCommonButtonBase の子クラスになっているようです。また、Abstract のようです。よって、BP 側で継承した Widget Blueprint を作成します。

今回は WBP_BoundActionButton としました。

上記のように、Text_ActionName という名前の Text Block 、そして InputActionWidget という名前の CommonActionWidget を用意しています。ここでは、名前と要素をこの通り用意しないとコンパイルエラーとなりました。

プロパティは特に変更はしませんが、Graph の方は以前作成した CommonButtonBase の継承クラスと同様に以下のようにしています。

作成できたら、WBP_Menu に配置している Action Bar のプロパティに設定します。

実行

WBP_MenuIs Back Action Displayed in Action Bar か、Display in Action Bar のいずれかにチェックが入っていれば以下のように右端の Default Back が有効になることが分かります。

Keyboard Gamepad

前回の記事で Default Back Action は「入力だけ受け付ける」のように書きましたが、この Action Bar を使うことでアイコンの表示もできることが分かりました。

他のボタンも Action Bar に表示してみる

Display in Action Bar (bDisplayInActionBar) のオプションは、UCommonUserWidget に定義されており、これは CommonActivatableWidget だけでなく、CommonButtonBase の親でもあります。

つまり、すでに WBP_Menu に配置している BackForward ボタンも Action Bar に表示できます。

パッと用途は思いつきませんが、配置済のボタンを Hidden にしても、Action Bar の方には表示されるため(Action Bar に元のボタンを表示している訳ではなく、同様の Input Action を Action Bar の方のボタンに設定しているだけなので)、何か使い道がありそうな気もします。

まとめ

デフォルトナビゲーションの流れで Action Bar について確認しました。どうしてもドキュメントが見つけられず正直これでいいのか感はあります 😅

Lyra の方も確認しましたが、W_BottomActionBarW_BoundActionButton の組み合わせで今回と同様に Action Bar を使っている例を見ることができました。