お世話になっております。
PC版でのコントローラの扱いにつきましてご質問がございます。
Unreal Engine4の仕様上、
XInput、DualShock 4のコントローラが同じ数、接続されている場合、
同じ種類のコントローラについては、
各コントローラを別のコントローラとして認識できますが、
違う種類のコントローラでは、
別のコントローラとして認識できない物と考えております。
例)「Xinput」×2個、「DualShock 4」×2個のコントローラが接続されている場合
XInput① と XInput②は、それぞれの入力を別で扱える。
DualShock 4① と DualShock 4②は、それぞれの入力を別で扱える。
XInput① と DualShock 4①は、同じ入力(コントローラ)として扱われてしまう。
XInput② と DualShock 4②は、同じ入力(コントローラ)として扱われてしまう。
こちら、XInput① と DualShock 4①を異なるコントローラとして認識させる、
また、XInput① と キーボード&マウスを異なるコントローラとして認識させる方法について、
ご教示頂く事は可能でありましょうか?
お世話になっております。
本件お時間を頂いており申し訳ございません、調査致しますのでもう少々お待ち下さい。
お世話になっております。
ご連絡が遅くなってしまい申し訳ございません。まず結論を先に申し上げますと、ご要望のことを実現するにはエンジンを独自に拡張して頂く必要がございます。以下、現状の動作と拡張の方針についてご説明いたします。
1. ローカル(1つの画面)での複数Device割り当てについて
まずUE4側として設定で出来ることについてのご説明ですが、デフォルトではPlayer0にGamepad(XInputの接続1、 DualShock4の接続1)及びKeyboardが割り当てられます。ProjectSettingsにあるSkipAssigningGamepadToPlayer1を有効にすることで、Gamepad(XInputの接続1、 DualShock4の接続1)の接続をPlayer1に割り当てることができます。これでKeyBoardはPlayer0、GamepadはPlayer1として別デバイスでの操作が可能になります。
この設定はKeyboardの入力をPlayer0、Gamepadからの入力があった場合は単にControllerIdをインクリメントしてPlayer1として割り当てるという簡単な仕組みではあります。以下の箇所で処理をおこなっています。
-
UGameViewportClient::InputKey()
if (NumLocalPlayers > 1 && Key.IsGamepadKey() && GetDefault()->bOffsetPlayerGamepadIds)
{
++ControllerId;
}
-
UGameViewportClient::InputAxis()
if (NumLocalPlayers > 1 && Key.IsGamepadKey() && GetDefault()->bOffsetPlayerGamepadIds)
{
++ControllerId;
}
2. Gamepad、Keyboardの入力について
次にUE4でのGamepadとKeyboardの接続毎の入力判定についてですが、GamepadについてはXInput、DualShock4共に最大4つの接続を常に監視していて、接続された順番にPlayer0から順番に割り当てが行われます。XInputの入力イベントはXInputInterface.cppのXInputInterface::SendControllerEvents()、DualShock4の入力イベントはPS4Controllers.hのSendControllerEvents()で毎フレームチェックしています。そして何かの入力があった場合はOnControllerButtonPressed()などのメッセージハンドラを通じてイベントを通知します。ここで渡しているControllerIdは接続されている順番に0~3を渡していて、それぞれに対応するPlayerで受信しています。よってXInput及びDualShock4は同一Playerに対する入力を受け付けるようになっています。Keyboardに関しては接続数に関係無く、単にWindowでの入力イベントとして処理しています。これは上記と同様にFWindowsApplication::ProcessDeferredMessage()にてOnKeyDownなどのイベントをメッセージハンドラ経由で通知しています。この過程においてKeyboardの接続状況を見ていないため、残念ながら複数の接続を別の入力として認識することはできません。
3. コントローラ別及びキーボード別で認識する方法ついて
- XInput① と DualShock 4①を異なるコントローラとして認識させる方法
- XInput① と キーボード&マウスを異なるコントローラとして認識させる方法
まず1)については2.で説明しました、各XInputとDualShock4の入力を処理する際にControllerIdをご希望の番号に上書きすることになります。残念ながら現在は接続順に入力を処理するという流れなので、どのPlayerにどのGamepadを割り当てるかをゲーム側、もしくは.iniファイルなどで定義し、各入力処理を判定する前にControllerIdとして割り当てておくことで、Playerに応じて入力を取ることができるかと思います。
次に2)については、現在キーボードの識別を行っていないので、まずはキーボードの識別を行うところから始めて頂くことになるかと思います。そして1)と同様にControllerIdを個別に割り当てることで、入力とデバイスを分離することが可能かと思います。
よろしくお願いします。
お世話になっております。
ご返答ありがとうございます。
挙げて頂いた拡張方針を基にこちらで対応の検討してみます。
どうもありがとうございました。