【UE5/UE5.1】Set Input Mode UI Only の癖が強い
Set Input Mode... のノードは三つありますが
その中の「Set Input Mode UI Only」の癖が強くて扱いが難しいと感じた...という内容です。
※ 2022-12-26:Input Mapping Context 使う を追加
※ 2022-12-26:「Set Game Paused」を使う を追加
本題
Widget を表示する時、入力の所有権を UI 側に移すような動きになる「Set Input Mode UI Only」を使うと簡単に UI のみの操作を取ることができます。
(所有権を移すという表現が合ってるか微妙な所ですがそういう風に勝手に解釈しております)
しかし、キャラクターが移動中などキー入力がある状態で Widget を表示すると凄く癖のある挙動をします。
例えばインタラクト可能なオブジェクトがあり、インタラクトボタンを連打しながらそこに向かって移動しているとします。
インタラクトキーが反応し、Widget の表示と「Set Input Mode UI Only」を組み合わせている場合、Widget は表示されますが、なにか対策をしなければ、キー入力をしていないのにキャラの移動はそのまま継続され進み続けます。
UI Only に切り替えたタイミングでキーボードの入力が受付けなくなるようで、移動は止まらないし UI を閉じるキーを押しても反応しない(閉じれない)という面倒な挙動を示します。
恐らくですがキーを離したという情報が伝わってなくてまだ移動中という判定が続いてるような感じがしました。
PC ゲームだと UI 操作に切り替える時
Get Player Controller-> Set Show Mouse Cursor を利用することも多そうに思いますが、UI Only でもデフォルトではマウスカーソルの入力は受付けるので Button Widget などで閉じれるような仕組みを設けておけば大丈夫そうには思います。
(その際「Set Input Mode Game Only」や「Set Show Mouse Cursor」は False にしたりなど必要)
しかし、ゲーム内で本を調べるなどでテキストが出るだけの UI があり、キーを押したら閉じればいいような挙動に、一々マウスカーソルを閉じるボタンに合わせて閉じる...というのも操作感は悪いです。
「Set Input Mode UI Only」+キャラの移動を停止
移動を止めたいだけなら、
Get Player Character-> Disable Movement(Character Movement)で無理やり止めることは出来ました。
UI Only なのでキー入力を受付けるよう例えば Widget 側で関数の「On Key Down」をオーバーライドし、インタラクトボタンに対応するなどで対応は出来そうです。
ただ私の場合は「Client Start Camera Shake」を使い、移動中に Camera Shake を入れているんですが「Disable Movement」で止めてもカメラの振動は止まりませんでした。
直前に「Client Stop Camera Shake」を入れると振動を止めることができるので、例えば「Delay」を使って少し時間を稼いでから「Set Input Mode UI Only」に繋げることで一応回避できたような気もしますがこれも力技な気もします。
キャラの移動とカメラ移動をフラグで監視する
非常に不恰好ですがキャラの移動の前にインタラクト中かどうかのフラグを用いて移動中・カメラ操作中は一生監視しておく方法だとどうか確認しました。
そうすると「Set Input Mode~」を使わなくてもフラグで弾いているのでキャラの移動やカメラ振動は止まり、カメラ操作も受付けず、入力はそのまま生きているのでインタラクトボタンを押して閉じるということが可能でした。
インベントリを開く場合は UI 操作が必要なので「Set Input Mode Game And UI」を利用すれば、実質 UI 操作だけ可能+キー入力は生きたままにすることができました。
(個人的には凄く嫌ですがフラグの ON/OFF だけ管理すればいいので扱い自体はかなり楽だと感じました。)
「Set Input Mode Game And UI」を使う
https://twitter.com/O_Y_G/status/1603230854301749248
CGとかさんより「Disable Movement(Character Movement)」と「Set Game Paused」を教えて頂きました。
本当にありがとうございます!!
結果的に上記方法でやりたかったことが実現できました!
「Set Input Mode Game And UI」を使うので Game に対しての入力はなくならず、「Disable Movement」でキャラの移動が止まったらカメラ振動も連動して止まりました。
キー入力で UI を閉じることもできるし、マウスカーソルも出るので UI 操作も可能です。
勝手な思い込みで、UI に操作が移ったらそのままキャラも止まると思っていたためこんなことが起こると思ってませんでしたw
「Set Game Paused」を使う
これはゲームそのものを今の状態で一時停止する時に使えそうな関数でした。
キャラやカメラが移動中に止めると画面ブレの状態で止まるので、ゲームによってはこういう方法で止める方法もいいなと思いました。
「Set Game Paused」を使う場合は、その間キー入力が取れないようなので、キー入力を受け付けるボタンを用意しないといけません。
▼ プロジェクト設定> インプットで軸・アクションマッピングの場合
Pause 中に取りたい入力イベントを選択し、「詳細」パネルに表示される「Execute when Paused」にチェックを入れるとこのキーが Pause 中に有効になります。
▼ Enhanced Input の場合
Enhanced Input の場合は Pause 中に取りたい入力の Input Action を開き、「Trigger when Paused」にチェックを入れるとこのキーが Pause 中に有効になります。
Input Mapping Context 使う
「Set Input Mode Game And UI」だと UI もゲーム操作も可能になりますが、UI を表示するタイミングで Enhanced Input の Add Mapping Context を利用し、UI を操作する用の入力アクションを追加します。
Add Mapping Context は必要に応じて Priority の引数をメインの Add Mapping Context した時よりも大きくしておきます。
Priority や Add Mapping Context については、以前の記事で触れています。
【UE5】Enhanced Input:Priority や Consume Input の検証
こうすることで、キャラの移動とは別に UI 専用の操作をすることができるため結構簡単に切り替えが出来ると思いました。
私の場合は、キャラ移動などのメインの Input Mapping Context をこのタイミングで Remove Mapping Context を使って削除しています。
Enhanced Input だと入力がアセットになっているのでこういう付け替えが出来るので凄く便利だと感じました。
おまけ
UE5.1 だと引数に Flush Input が追加されている
https://twitter.com/UE5wancoro/status/1603066442001174534
UE5.1 で検証をしてみようと思った時「Set Input Mode~」系のノードに Flush Input という引数を見かけました。
UE5.0.3 にはなかったため、 UE5.1 の Set Input Mode UI Only 公式ドキュメント も覗きましたが載ってませんでした。
名前から何となく察してはいましたが、チェックを入れて「Set Input Mode UI Only」で確認するとキャラの移動とカメラの振動が止まるので、恐らく Player Controller(?)に対して入力の Flush 処理を行っているんだと思われます。
UI Only であることに変わりはないので UI の操作をどうするかは別途考えなくてはいけません。
Common UI:Activatable Widget はどう?
https://twitter.com/UE5wancoro/status/1565871633029812225
以前の検証で Common UI の Activatable Widget を利用することで、恐らくデフォルトで UI Only の操作になり「Set Show Mouse Cursor」が True の挙動を示すことを確認できておりました。
そこで、今回のケースではどうなのか改めて確認するとなんとキャラの移動とカメラ振動が止まってました!
余談ですが「Activate Widget」した後にマウスカーソルも自動で表示されますが、その後に「Set Show Mouse Cursor」を False にしてもカーソルは消えませんでした。「Deactivate Widget」後であれば消えたので、そういう挙動なのかも?
どういう条件で止まるのか、デフォルトでそういう挙動なのか気になったため下記条件で検証してみました。
- 「Set Input Mode~」は使わない
- Widget 表示は「Add to Viewport」→「Activate Widget」のみ
- 「Get Desired Focus Target」のオーバーライド有無
- 「Deactivate Widget」は後始末のため考慮せず
その結果のまとめがこの画像です。
表示する UI に対し、なんらかの Widget が Activate された時点でキャラ移動とカメラの振動が止まるという結果になりました。
最後に
そんな感じで「Set Input Mode UI Only」の癖が凄いという内容でした。
UI Only とはあまり仲良くなれた気はしませんが、今回の件で UI 表示する時の挙動についてとても勉強になったと思います。
こういう当たり前のように使う機能の基本的な挙動が全然わかってないので、1個覚えるごとに2-3個は分からない所が出てくるので本当に難しいですw
改めまして CGとかさんにお礼申し上げます。
本当に本当にありがとうございました!!!!