Input Systemでゲームパッドのボタンやスティックなどの「場所」はどうやって扱えば良いの?
これらの情報はControl Pathという文字列として扱われるわ。例えばBindingなどに指定する情報がそうだわ。
Input Systemでは、キーボードのボタンやマウス移動量、ゲームパッドのスティックといったControlの情報はControl Pathという文字列として扱われます。
参考:Controls | Input System | 1.5.1
例えば、Input Action Assetの編集でActionのBindingに割り当てる入力先がControl Pathです。
普段はドロップダウン形式で選択するUIですが、右側にある小さな「T」ボタンをクリックすると、実際のControl Pathの文字列として編集可能になります。
本記事では、このControl Pathの基本的な仕様や使い方について解説していきます。
- Unity 2022.3.0f1
- Input System 1.5.1
目次 非表示
前提条件
事前にInput Systemパッケージがインストールされ、有効化されているものとします。
ここまでの手順が分からない方は、以下記事を参考にセットアップを済ませてください。
Controlの基本的な仕組み
Input Systemでは、ゲームパッドやキーボード、これらに付いているボタン類などを全てControlとして管理します。
Controlは次のような階層構造として管理されます。
スクリプト中からはInputControl継承クラスとして扱われます。
参考:Class InputControl| Input System | 1.5.1
階層化されたControlはスラッシュ「/」区切りのパスとして表現されます。
Control Pathの基本構文
Control単体は次のような文字列で表現されます。
指定するものが4つありますが、すべてを指定する必要はなく、最低限どれか1つ指定すればよいです。基本的に数あるControlのどれを使うかを検索するために使われるものです。
また、階層化されたControlはスラッシュ「/」区切りで指定します。
layoutNameには、「Keyboard」「Gamepad」などのレイアウト名(Controlの型)を指定します。他にも、後述する子階層のControlで「Button」「Axis」などの名前も指定できます。
レイアウト名は「<」と「>」で囲んで指定します。
参考:Layouts | Input System | 1.5.1
usageNameには、「Submit」や「Back」など、予めControlに割り当てられているusages名を指定します。例えば、Escキーには「Back」と「Cancel」、Enterキーには「Submit」がusageとして予め割り当てられています。
usage名は「{」と「}」で囲んで指定します。
参考:Controls | Input System | 1.5.1
controlNameには、具体的なControl名を指定します。例えばゲームパッドの「DualShock4GamepadHID」やEnterキーの「enter」などといった名前です。
displayNameには、Controlの表示名を指定します。例えばキーボードのEnterキーの「Enter」などが該当します。
displayNameは「#(」と「)」で囲んで指定します。
構文の例
具体的なControl Pathの例をいくつか示します。
- <Gamepad>/rightTrigger
- 「Gamepad」というLayout名のControl配下の「rightTrigger」という名前のControl
- ゲームパッドの右トリガーを表す
- DualShock4GamepadHID/buttonEast
- 「DualShock4GamepadHID」という名前のControl配下の「buttonEast」という名前のControl
- DUALSHOCK 4コントローラーの〇ボタンを表す
- <Gamepad>/leftStick/left
- 「Gamepad」というLayout名のControl配下の「leftStick」という名前のControl配下の「left」という名前のControl
- ゲームパッドの左スティックの左入力を表す
- <Gamepad>/<Button>
- 「Gamepad」というLayout名のControl配下の「Button」というLayout名のControl
- ゲームパッドのボタン全体が対象となる
- <Keyboard>/#(Enter)
- 「Keyboard」というLayout名のControl配下の「Enter」という表示名のControl
- キーボードのEnterキーを表す
ワイルドカード表記
Control Pathには、「全て」を表すControlをアスタリスク「*」として指定可能です。
- <Gamepad>/*
- 「Gamepad」というLayout名のControl配下の「全て」のControl
- */{Submit}
- 「全て」のControl配下の「Submit」というusage名のControl
スクリプトからControl Pathを扱う
スクリプトではControl Pathは文字列(string型)として扱います。
シリアライズするフィールドに[InputControl]属性を付加すると、インスペクター上からControl Pathを編集するための専用UIに置き換わります。
参考:Class InputControlAttribute| Input System | 1.5.1
サンプルスクリプト
以下、インスペクターから指定されたControl Pathをログ出力するサンプルスクリプトです。
上記をControlPathExample.csという名前でUnityプロジェクトに保存し、適当なゲームオブジェクトにアタッチし、インスペクターよりControl Pathを設定してください。
実行結果
ゲームを実行すると、インスペクターから指定されたControl Pathの文字列がログ出力されるようになります。
Control Pathの構文を解析する
Control Pathはstring型の文字列として管理されますが、構文を解析することも可能です。
構文解析には、InputControlPath.Parseメソッドを用います。
参考:Class InputControlPath| Input System | 1.5.1
解析結果は、InputControlPath.ParsedPathComponent構造体のコレクションとして返されます。コレクションの各要素は、上層からパスで区切られたControl情報です。
参考:Struct InputControlPath.ParsedPathComponent| Input System | 1.5.1
サンプルスクリプト
以下、指定されたControl Path文字列を解析してログ出力する例です。
上記をParseExample.csという名前で保存し、適当なゲームオブジェクトにアタッチし、インスペクターよりControl Pathを設定すると機能するようになります。
実行結果
例えば、「<Gamepad>/dpad/down」というControl Pathが指定されると、以下のような結果になります。
上から順にLayout名が「Gamepad」のControl、名前がdpadのControl、名前がdownのControlという順番のコレクションがInputControlPath.Parseメソッドから返されていることが確認できます。
Control Pathから実際のControlを取得する
実際にActionなどとしてボタンやスティックなど各種Controlから入力を受け取るためには、Control Pathから実際のControlを取得する必要があります。
このようなControlはプログラム上ではInputControl継承クラスとして扱われます。
例えばボタンはButtonControl、スティックはStickControl、キーボードのキーはKeyControlという派生クラスとして実装されます。
単一のControlはInputSystem.FindControlメソッドから取得できます。
参考:Class InputSystem| Input System | 1.5.1
サンプルスクリプト
以下、与えられたControl PathからInputControlインスタンスを取得し、内容をログ出力する例です。取得に失敗したらその旨のメッセージを出力します。
上記をInputControlExample.csという名前でUnityプロジェクトに保存し、適当なゲームオブジェクトにアタッチすると機能します。
予めインスペクターよりControl Pathを設定してください。
実行結果
Control Pathに「<Keyboard>/enter」が指定されると、EnterキーのInputControlが得られ、その内容がログ出力されます。
レイアウトが「Key」だったり、親Controlが「Keyboard」だったり、usageに「Submit」が存在していたりといった情報が確認できます。
試しにControl Pathに親の「<Keyboard>」を指定してみると、次のような結果が得られます。
親Controlが存在しない代わりに、子Controlとして各種キーが大量に存在していることが確認できます。
複数のControlを取得する
前述の例では、単一のInputControlのみ取得していました。
しかし、実際にはControl Pathから複数のInputControlが得られるケースもあり得ます。例えばワイルドカードが指定されたControl Pathなどです。
これはInputSystem.FindControlsメソッドで取得できます。
テンプレート引数TControlを指定することで、得られるControlの型を制限できます。例えば、キーボードのキーに限定したい場合はKeyControl型を指定すれば良いです。
参考:Class InputSystem| Input System | 1.5.1
サンプルスクリプト
以下、指定されたControl Pathから複数のControlを列挙し、その内容をログ出力する例です。
上記をInputControlsExample.csという名前でUnityプロジェクトに保存し、適当なゲームオブジェクトにアタッチし、インスペクターよりControl Pathを設定します。
実行結果
例えば、「*/{Submit}」というControl Pathが指定されると、全てのデバイス直下の「Submit」というusageを持っているControlが列挙されます。
例ではキーボードとXboxコントローラーのSubmitボタンが得られていますが、他にもSubmitとなり得る候補は存在します。あくまでも接続され使用可能になっているControlのみが対象になっている点が特徴です。
さいごに
Control Pathは、キーボードやマウス、ゲームパッドなどのデバイスの他、これらのデバイスが保持しているボタンなどを表現します。
Control Pathは複数のControlを表すことも出来ます。
Controlは階層構造になっており、各種Controlはファイルパスのようにスラッシュ「/」区切りで表現されます。