お疲れ様です。
UMGのNavigationとEnhancedInputの関係に関して質問をお願い致します。
<br/>
Up,Down、Left、Rightキーを登録したMappinContextを有効化し、実際にキー入力を行います。
その際、FocusableなWidgetにフォーカスがある場合、Navigationで入力イベントが消費され、EnhancedInputのイベントが発生しないようなのですが、これを回避する(両イベントが発生する)方法はございませんでしょうか?
あわせて、入力イベントの消費箇所特定に関して、おすすめのデバッグ方法を教えて頂けませんでしょうか?
<br/>
よろしくお願いいたします。
[Attachment Removed]
基本的な入力イベントは"FSlateApplication::OnKeyDown()"から"SWidget::OnKeyDown()"に流れて行き、そこでナビゲーションキーであれば消費されます。
ただし、Slateの種類によってはオーバーライドで違った動きをするかもしれないので、"SWidget::OnKeyDown()"にブレークを仕掛けておき、到達しないようであれば問題のslateのオーバーライドを確認するといった形で進めると良いかもしれません。
FReply SWidget::OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent )
{
if (bCanSupportFocus && SupportsKeyboardFocus())
{
EUINavigation Direction = FSlateApplicationBase::Get().GetNavigationDirectionFromKey(InKeyEvent);
// It's the left stick return a navigation request of the correct direction
if (Direction != EUINavigation::Invalid)
{
const ENavigationGenesis Genesis = InKeyEvent.GetKey().IsGamepadKey() ? ENavigationGenesis::Controller : ENavigationGenesis::Keyboard;
return FReply::Handled().SetNavigation(Direction, Genesis);
}
}
return FReply::Unhandled();
}
[Attachment Removed]
t-nikaido1
(t-nikaido1)
3
お世話になっております。
Shibata Tsubasa 様、コメントありがとうございます。
こちらのご指摘の通りで、SWidget::OnKeyDown においてはナビゲーションにより入力イベントが消費(Handled として返される)ことにより入力イベントを処理するループ(FEventRouter::Route 関数内)から抜けてしまうため PlayerController へは入力が通らなくなります。
調べた限りではこれを回避するオプション等は無さそうです。
入力の消費箇所について特定できる統合された機能は用意されていないようですが、Slate と EnhancedInput それぞれについては以下のような手段があります。
Slate(UI)の場合
SlateDebugger によってフォーカスの移動・ナビゲーション等をログで確認できます。
slatedebugger.start で開始、slatedebugger.stop で終了します。
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/console-slate-debugger-in-unreal-engine?application_version=5.6
Viewport(EnhancedInput)の場合
showdebug enhancedinput コマンドにより有効になっている入力アクションの状態を確認できます。
[https://dev.epicgames.com/documentation/ja\-jp/unreal\-engine/enhanced\-input\-in\-unreal\-engine\#デバ��%8\[…]マンド](Unreal Engine の Enhanced Input | Unreal Engine 5.7 ドキュメンテーション | Epic Developer Community)
よろしくお願いいたします。
[Attachment Removed]
お疲れ様です。
ご回答ありがとうございます。
NavigationとEnhancedInputで同一キーを処理したい場合、どういった手段が考えられますでしょうか。
今のところ、Engine側に手を入れるしか無い(EnhancedInputの処理フローをなるべくそのまま利用したい)と考えているのですが、可能であればアプリーケーション側で処理を行いたいです。
単純なキーであれば InjectInputForAction の利用で解決できるのですが、複合キーの場合を想定すると、EnhancedInputの処理フローを利用した方が安全だと考えております。
よろしくお願いいたします。
[Attachment Removed]
お疲れ様です。
ご回答ありがとうございます。
InputPreProcessorの利用を検討します。
お忙しい所ご対応ありがとうございました。
大変助かりました。
[Attachment Removed]
t-nikaido1
(t-nikaido1)
6
先にご案内したように、Navigation に使用された入力イベントはそこで消費される作りになっています。
意図的に迂回する手段は存在するものの、これにより大小の問題が生じる場合があることは予めご承知下さい。
Slate への入力より先に処理される InputPreProcessor という段階があり、こちらでの対処が比較的簡単かと思います。
InputPreProcessor はほぼ状況に関わらず入力イベントを処理できるため強力ですが、それだけに取り扱いには注意して下さい。
InputPreProcessor の登録と解除は以下のように行えます。
FSlateApplication::Get().RegisterInputPreProcessor(InputPreProcessor);
FSlateApplication::Get().UnregisterInputPreProcessor(InputPreProcessor);
エンジン内にも幾つか用例がありますので、そちらを参考にされるのが良いかと思います。
外部サイトとなりますが単純なサンプルとしては以下が分かりやすいです。
https://shama-coo.hatenablog.com/entry/2020/03/20/182505#:~:text=%23pragma%20once%20%23include%20%22CoreMinimal,%E3%81%AE%E3%82%AD%E3%83%BC%E9%9B%A2%E4%B8%8A%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88.
入力を処理する関数(HandleXXX)において APlayerController::InputKey を呼び出すことで Navigation 等をバイパスして入力イベントを PlayerController へ渡すようなことができます。
また、false を返すことで入力イベントを消費せず Slate へ「透過」させることができます。
これにより PlayerController を通した入力処理と Navigation を同時に動作させることが可能です。
よろしくお願いいたします。
[Attachment Removed]