C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

UE4: PS4 の DualShock4 コントローラーを Windows PC に Bluetooth 接続して UE4 の Input で使う方法

1. PS4 DS4 を Bluetooth で PC に接続

  1. DS4 を SHARE + PS の同時長押しで Bluetooth ペアリングモードにする
    • このモードになるとインジケーターがピピッ的に断続的に発光する状態になる
  2. Windows PC の設定 "Bluetooth & other devices" からペアリングする(日本語でもたぶんそれっぽいカタカナになっているだけでしょう、たぶん)
    • 設定画面最上部の "Add Bluetooth or other device" をポチッとして "Bluetooth" を選択し、 Wireless Controller が認識されたらポチるだけです。

これだけで DS4 を Windows PC で使用可能になります。動作テストは Monster Hunter: World などで適当にどうぞ。STEAM を使っている場合には、 STEAM の設定機能から DS4 のインジケーターの発光色を変更するなどもできます。

f:id:USAGI-WRP:20180818030651p:plain

f:id:USAGI-WRP:20180818031041p:plain

3. UE4 のプロジェクトから使えるようにする

方法が幾つかある様子ですが、簡単に期待動作が得られたものは次の3つのうちでは1つだけでした。

  1. UE4 標準の Built-In プラグイン Windows RawInput を使う (期待動作せず)
  2. UE4 標準の Built-In プラグイン Steam Controller を使う(ようわからんかった)
  3. katze7514/UEDirectInputPadPlugin プラグインを使う(まともに動く方法はこれだった)

3.1. Windows RawInput で遭遇した問題

Windows RawInputのドキュメントを参考に試してみたものの…

  1. 軸の入力がおかしい。 Offset が必要なだけかと思いましたが、 Offset を設定してもセンターを調整できない状態でした💀
  2. DS4 の ○ ボタンなどの応答がおかしい。押してもイベントが発火しない事の方が多く、何度か押しているとたまに Pressed が来る状態でこれはもうダメだと思いました💀

こんなところのソースに興味は無いし、他の方法も試せるのでこれはもう諦めました。(DirectInputの複数デバイス、アナログ入力、フォースフィードバックの実装を書いた事はたぶん人生で3回くらいはありますが、また書きたいとも思いません😅)

Note: Steam が動作中は DirectInput コントローラーを Steam が専有するため、 UE4Editor で開いたプロジェクトどころか、Windows の Game Controllers やそこから開けるコントローラーのキャリブレーションとテストができるプロパティーウィンドウなどもデバイスの認識はしているものの入力は一切受け取れない状態になります。 Windows RawInput を試す場合は Steam が起動していない状態を確認しましょう。(これにもちょっとやられました…💀)

3.2. Steam Controller を使おうと思ったものの…

Steam Controller プラグインを有効にしても Windows RawInput のような設定画面も用意されておらず、 Steam の入力イベントもバックボタンとタッチがあるのみなので、一般的な軸やボタン群は自動的に標準の XInput パッドへ割り当てでもされるのかな、と勝手に期待して実行してみるも反応せず💀 Steam Online Subsystem プラグインも必要なのだろうか、など有効にしてみたものの、特に変化もなく💀

UE4側に有用でわかりやすいドキュメントもなさそうだし、STEAMのドキュメントからはUE4プラグインの内部処理でやってくれるであろう取得方法とかしかでてきませんし、使い方がようわからんし、ソース見るのはもう1つ見つけていた方法を試してもダメだった後にしようと思いとりあえず諦めました💀

3.3. katze7514/UEDirectInputPadPlugin で幸せになる

DirectInput 汎用のプラグインのため、 PS4 の DS4 を使う場合にも一部リマップやリマップ相当の対処は必要でしたが、ほぼ期待動作してくれました😃 若干期待動作しなかった機能はリマップ相当の代替手段で対処すれば、見かけ上は期待動作になります。

f:id:USAGI-WRP:20180818072945p:plain

↑の絵のようにリマップすると、はじめのリマップノード2つ DS4 のクロスとサークルへの割り当ては期待動作しますが、残念ながら3つめのリマップノードの右スティックのY軸への割り当ての Negative は動作しないようでした。この部分はプロジェクトの設定の Engine の Input 設定を反転させるなり、それを使う実装側で反転させる係数を書ければその場しのぎはできます。

ただし、XInputのコントローラーと PS4 の DS4 のコントローラーどちらにも同様の動作を設定したい場合は接続状態を確認して係数を反転させてあげないと、一般的な3Dアプリの操作系でいえばカメラのY軸が接続するコントローラーによって順方向と逆方向がリバースしてしまうという怪奇現象になり、少々面倒です。これは後ほど Issues へ Negative が期待動作していない旨をポストしておこうと思います。パッチまで投げるかは…気分と必要の次第としつつ。

追記: Issue投げました → Set Key Map の Negative が期待動作しない #5

追記追記: プラグインを開発された katze7514 さんから「その用途なら Set Key MapNegative じゃなくて Set Axis ReverseReverse でできるよ!」と↑の Issue で教えて頂きました。私がプラグインの仕様を勘違いしてしまっていただけで綺麗に意図した動作を組み込めました😃 )

f:id:USAGI-WRP:20180819091600p:plain

↑今回の目的で組むべきだった本来のノードとパラメーター。

A. おまけ、接続したコントローラーの VID, PID の確認の仕方

Windows RawInput プラグインを使う場合に確認が必要となります。

  1. "Device Manager" の "Human Interface Devices" を展開して HID-compliant game controller を探す
  2. プロパティーを表示する
  3. "Details" の "Property" を "Hardware Ids" に変更して VID とか PID っぽい値を確認する

DS4(CUH-ZCT2J)の場合は VID=054C PID=09CC のようです。 VID は Vendor ID 、 PID は Product ID で、それぞれ販売元と製品を一意に認識するための ID です。この番号はデバイスに自由に与えられるものでは無く(野生のUSBデバイスを作ればものとしては作れるけれど)、通常一般的に流通している USB 製品にはすべて割り当てが存在します。DS4でも型式が違えば、PIDが異なる可能性があります。また、Horiのゲームパッドなど販売元が異なるコントローラーではVIDも異なる可能性があります。横着せず、実際に挿したデバイスの VID, PID を調べてから進みましょう。

f:id:USAGI-WRP:20180818031726p:plain

f:id:USAGI-WRP:20180818031919p:plain

ゲームエンジンをいじりたいならいいんですが、立派なフレームワークの上でそれほどマイナーでもなかろうゲームコントローラーが標準機能で安心して使えない状況はちょっとショッキングな事態でした。これまでゲームコントローラーの動作試験は XInput のゲームパッドだけで行っていたので気づきませんでしたが、 UE4PS4 の DS4 を使いたいというありがち…であろうと思われるニーズで少々苦労があるとは思いもしませんでした。

とりま、動いたのでとりあえずヨシという事にします😃
(はいはいヨシネコさんでいいですよ…DirectInputとかSTEAM Controllerの実装書くモチベーションは特にありませんしー。 )

今回は katze7514/UEDirectInputPadPlugin の存在に感謝しつつありがたく使わせて頂く事にします。