ゲームコントローラーの対応【Unity6】

絶対調味ロジック

前回の「入力システムの一本化」にてインプット基盤ができあがったので、
今回はゲームコントローラーが反応するかどうかの試運転です。
UI画面との兼ね合いもあるので、とりあえずテキスト進行ができれば合格とします。

対象デバイス

エレコム JC-DD01BK

製品名:エレコム JC-DD01BK (ドラゴンズドグマ オンライン推奨モデル)
通信規格:DirectInput (レガシー規格 / HID準拠) ← 伏線…

2024年頃、当時アクションゲームを作り始めたときに購入したものと思われます。

特典としてドラゴンズドグマ内アイテムコードが付与されており、交換期間が2015~2016年となっていました。
物としては2年前どころか、10年前のものですかね?((;゚Д゚)

ドラゴンズドグマは遊んでいませんでしたが、このモデルがお手頃価格だったのでしょう…

物理・OS階層の確認

まずはWindows11内でのデバイス検知を確認します。
当時は「JoyToKey」を使ってボタンなどを割り振っていたため、今回はちゃんとデフォルト検知から試みます。
遥か古(いにしえ)では、PS1コントローラーに「スマートジョイパッド」を接続してPCに繋いでいましたね。

・「Winキー + R」で「ファイル名を指定して実行」内に「joy.cpl」と打ち込む。
・コントロールパネル内の検索に
 「ゲームコントローラー」と打ち込み「USBゲームコントローラーのセットアップ」をクリックする。

どちらかを行うと「ゲームコントローラーウィンドウ」が開くので、繋いだコントローラーを選びます。

プロパティを押すとテストウィンドウが開くので、コントローラーのボタンを押して検知しているか確認できます。

エレコムコントローラーが「PC Game Controller」として正常に認識され、
ボタン信号がOSに届いていることが確認できました。

Unity6環境への適合

Unity6 + Input System Package」環境なので、
最新の「UnityEngine.InputSystem API」を使用した確認用テストスクリプトを書いてもらいました。

コントローラーの検知のみなので、各Actionとはまだ紐づいていません。
Unity内での検知ができているのかだけが目的です。

Unityのコンソール上で、
デバイス名および各ボタン(button2, button3, button7等)の押下ログをリアルタイムで確認できました。
10年前のデバイスでも「Windows11」「Unity6000.3」ともに反応してくれたので良かったです。

現在の技術的構成

  • Unityバージョン:6000.3.10f (URP)
  • 入力システム:Input System Package (1.18.0)
  • 認識方法:HID デバイスとして認識。

重要
このコントローラーは Gamepad クラス(Xbox/PS用)ではなく、
Joystick または HID クラスとして扱われます。

今回はこの「認識方法」の知識不足のため、コントローラー反応無し地獄に陥りました。(´・ω・`)
Claudeの全トークンを、修正・確認・ダメです、の繰り返しに使ってしまってもったいなかったです。

コントローラー導入・実装

Gamepadのbindingを追加

Claudeには「現状の操作系列のすべてをコントローラーでもできるように」と依頼。
ステップ1でActionに追加。
ステップ2以降でUI画面への各対応、スクリプト修正。
という流れでしたが、今回はステップ1で大いにつまずくはめになりました。

ActionAction追加するbinding
UI / AdvanceSouth Button [Gamepad](A)
UI / CancelEast Button [Gamepad](B)
UI / BacklogCloseEast Button [Gamepad](B)
UI / SkipLeft Shoulder [Gamepad](LB)
UI / AutoRight Shoulder [Gamepad](RB)
UI / ScrollYRight Stick [Gamepad](Y軸)
System / QuitStart [Gamepad]

先に作ってあった各「Actions」にゲームパッド用のボタンを適用させていきます。
とりあえずシナリオ進行の左クリックが、ゲームパッドのボタンに適応されて、ゲームが進むことを目標とします。
Actionsでいうと「Advance」になります。

ここでいったん積むことになります(笑
何をやっても、どこの設定を直しても、一向にコントローラーの反応がありませんでした。
インプットデバッグ」という検知ウィンドウで確かめるも、追加したバインドが表示されない状態が続きます。

マウスの左クリックしか表示されない!

実装における重要な知見

実はバインド設定の「Gamepad」は、

  • Xbox:Android Xbox One Controller / iOS Xbox One Gamepad
  • PlaySrtaition:DualSense HID / Android DualShock 4 / iOS DualShock 4 / iOS DualSense
  • Andrid Gmapad
  • iOS Gmapad
  • Nimbus Gmapad
  • WebGL Gmapad
  • Switch Pro Controller

上記のみの対応となっているようです。

重要
このコントローラーは Gamepad クラス(Xbox/PS用)ではなく、
Joystick または HID クラスとして扱われます。

先の重要情報がここで活きてきます。

つまり「Gmapad」ではなく「Joystick」を選ばないといけなかったようです。
コントローラーといえばゲームパッドだし、
ジョイスティックといったら高橋名人の「ハドソンジョイスティック」じゃろがい!(#^ω^)

というわけで、ちゃんと「Joystick」のボタンで選びなおします。

しっかり「PC Game Controller」ってなっているんですよね…
最初からゲームパッドではなく、ゲームコントローラーという認識じゃないといけなかったのです。
実は「Unity6環境への適合」の画像をみると、しっかり「PC Game Controller」と検知されているという…

インプットデバックウィンドウにも、ちゃんと認識されています。
もちろん左クリック進行がコントローラーボタンで行うことができました。

しかし不幸中の幸いでもありました。
最初から最新系PS用コントローラーなどを使ってしまっていたら、
その他「古い入力機」の存在に気がつかずに、ハイブリッド設定にできなかったと思われます。(*´ω`*)

あとはUI画面などに対応させるステップ2以降がたっぷりと残っているのですが、
UIデザイン配置の兼ね合いもありそうなので、いったんここまでにしておこうと思います。

あ、そうなると最新系PS用コントローラーも購入しておかないと、動作確認できないですね…
必要経費…

マルチデバイス対応の核

Xbox/PS用・その他のコントロールデバイスの2つのバインド設定をしておく必要があり、
つまりUnity6でこの種の古いパッドを対応させるための「正攻法」は以下の通りになります。

バインディングの二重構造(ハイブリッド戦略)
一つのアクション(例:決定/Submit)に対し、以下の2つのパスを共存させます。

登録パスターゲットデバイス役割
South Button [Gamepad]Xbox, PS4/5, Switch Pro主要な現行パッドを自動で網羅する。
Button 2 [PC Game Controller]その他HID主要パッドに分類されない「古い入力機」を拾う。

注意点
特定の製品名(HID::PC Game Controller)でパスを固定すると他社製品で動かなくなるため、
Joystick という広いカテゴリー名で登録するのがポイントです。

↑「自分が使っているデバイスのボタン」を指定することもできるため、それはしないように、ということです。

右スティックと十字キーの扱い

  • 右スティック:「Stick」ではなく「Axis」として認識される場合があるため、
    「Input Debugger」で軸番号(X/Y/Z/Rz)を特定してマッピングする必要があります。
  • 十字キー:ボタンではなく「Hatswitch」として認識される場合があります。

将来的な展望:キーコンフィグ(Rebinding)

DirectInputパッド(その他HID)は、
製品ごとにボタン番号(例:Aボタンが2番だったり0番だったりする)が異なるため、
開発者が全パターンを予測してバインドするのは不可能ということです。

最終的には、
ユーザーが自分のパッドに合わせてボタンを割り当て直せる 「リバインディング機能(キーコンフィグ)」
アプリ内に実装することで、あらゆる変則パッドに完全対応することが可能になります。

キーコンフィグか…
これもまた大変そうですね。

コメント