はじめに
この記事はUnreal Engine (UE) Advent Calendar 2024の11日目です。
概要
ImGuiとても便利ですね。デバッグメニューを作るならこれ一択といった感じでデファクトスタンダードとなっています。
いろいろな講演で目にするデバッグメニューはほとんどImGuiです。
そんなImGuiをUnrealEngineでも使用できます。導入方法は無数の記事があるので検索してください。
ここではCommonUIプラグインとImGuiを同時に使用する場合に決定ボタン(XboxGamePadならAボタン)が効かなくなる問題と対策方法を書きます。
問題
ImGuiを導入してデバッグメニューを作っていき、ゲームパッドで操作もしていたとき、そろそろインゲームUIを作成していこうとCommonUIプラグインを使うことにしました。
UMGとCommonUIで順調にインゲームUIを作っていきます。
EnhancedInputも使い、InputActionやInputMappingContextでゲームプレイとUIで入力の切り替えも順調です。
一通りできてきたころ、デバッグメニューを使用するユーザーからこんな報告がきます。
「デバッグメニューでAボタンが効いてません。」
関連しそうな変更は加えていないのに、一体何が原因でしょうか
原因
バグ発生前までバージョンを戻したり、新規プロジェクトで検証していくと、CommonUIを有効化しCommonGameViewportClientへ変更した場合に発生することが判明します。
この変更によって
CommonInputSubsystemからFSlateApplication::RegisterInputPreProcessorが追加で呼ばれCommonInputPreProcessorが追加されます。
このPreProcessorがあるとAボタン操作が効かなくなります。
対策
Yボタンを使う
ImGuiをXboxGamePadで操作する場合、実はYボタンも決定ボタンとして扱っています。
Aボタンの代わりにYボタン使ってもらえれば問題は回避できます。
エンジン改造する
CommonInputSubsystemが持つCommonInputPreProcessorから、決定ボタンの動作がImGuiに伝わらなくなります。
デバッグメニューを開くときにこのPreProcessorをUnregister,閉じるときにRegisterしおなおすことで無効にできます。
protected:
TSharedPtr<FCommonInputPreprocessor> CommonInputPreprocessor;
を以下のようにPublicにします。
public:
TSharedPtr<FCommonInputPreprocessor> CommonInputPreprocessor;
とすれば取得できるようになるので、デバッグメニュー開閉時にUnregister/Registerを行います。
void UMyCheatManager::Hoge()
{
auto PlayerController = GetPlayerController();
auto LocalPlayerController = PlayerController->GetLocalPlayer();
auto&& CommonInput = UCommonInputSubsystem::Get(LocalPlayerController);
auto&& Slate = FSlateApplication::Get();
Slate.UnregisterInputPreProcessor(CommonInput->CommonInputPreprocessor);
}
void UMyCheatManager::Hoge2()
{
auto PlayerController = GetPlayerController();
auto LocalPlayerController = PlayerController->GetLocalPlayer();
auto&& CommonInput = UCommonInputSubsystem::Get(LocalPlayerController);
auto&& Slate = FSlateApplication::Get();
Slate.RegisterInputPreProcessor(CommonInput->CommonInputPreprocessor);
}
この方法だとデバッグメニューを常時表示しながらゲーム操作するときどうなるんだという問題があります。
終わり
エンジン改造はできればしたくないので、Yボタンを使ってもらうようにしましょう。
CommonInputPreProcessorをUnregister/Registerするのも、デバッグメニューを常時表示しながらテストしているときにどうするんだという問題もあります。
デバッグメニューはキーボード・マウスの操作のみをサポートする。と割り切ってしまうのもありです。