次のように、ゲームパッドのスティック入力を8方向にスナップさせる方法を知りたいの…
Composite Bindingを使えば簡単にできるわ。Processorを自作すればより高度なスナップ処理も可能だわ。
Input Systemのスティックなどの2軸入力を8方向にスナップさせる方法の解説記事です。
次の方法で実現可能です。
- 2D Vector Compositeを用いる
- スナップ処理を行うProcessorを自作する
前者はノーコーディングでできる反面、入力値は必ず0と1に2値化した値となります。
後者はコーディングが必要ですが、前者の挙動に加え、例えば方向はスナップさせるが入力値の大きさは連続的にするといった要件にも対応できます。
本記事では、このような2軸入力を8方向にスナップさせる方法を解説していきます。
- Unity 2023.1.0f1
- Input System 1.6.1
目次 非表示
前提条件
予めInput Systemパッケージがインストールされ、有効化されているものとします。
この手順およびInput Systemの基本的な使い方については、以下記事をご覧ください。
また、Input Action経由で入力を受け取るものとします。
Input Actionの使い方は以下記事をご覧ください。
Vector 2 Compositeで8方向にスナップする
Input Systemでは、複数の入力を合成するComposite Bindingという機能があります。
参考:Input Bindings | Input System | 1.6.3
このComposite Bindingのプリセットの一つである2D Vector Compositeを使うと、結果として8方向へのスナップ入力が実現できます。
参考:Input Bindings | Input System | 1.6.3
2D Vector Compositeは4方向の入力を2軸入力(Vector2型)に合成するComposite Bindingですが、ModeにDigital Normalizedを設定すると、8方向にスナップされた結果が得られます。
処理としては、各方向の入力値を0と1に2値化して2軸入力に合成し、合成した入力値の大きさを0または1にスナップしています。
スティック入力はVector2型ですが、上下左右の4方向の入力を子のControlとして持っているため、これらを2D Vector Compositeの各方向に指定すれば良いです。
4方向ボタン入力の場合
該当するActionのAction TypeをValue、Control TypeをVector 2に設定します。
そして、Actionの+アイコンからAdd Up\Down\Left\Right Compositeを選択し、ModeをDigital Normalizedに設定します。
Modeは必ずDigital Normalizedとしてください。これ以外のモードにすると、正しくスナップされなかったり、斜め方向入力が大きくなったりしてしまいます。
最後に、各方向のBindingにボタンを割り当てます。例ではWASDキーとしました。
当環境のUnity 2023.1.0f1では、次のようにPathの設定画面でListenボタンなどが隠れてしまう現象を確認しました。
Listenボタン自体は押せる状態になっています。今後のアップデートで修正される可能性があります。
使用例
前述のActionで設定した2軸入力をスクリプトから受け取れば、8方向入力が得られます。
ここでは、次のように取得した入力値に基づいてオブジェクトを移動させるものとします。
上記をMoveExample.csという名前でUnityプロジェクトに保存し、移動させたいゲームオブジェクトにアタッチし、インスペクターからActionと移動の速さを設定します。
例では、正方形画像に対して前述のActionを割り当てることとします。
実行結果
8方向にスナップされて移動するようになりました。斜め移動でも上下左右と速さが同じになるように正規化されています。
スティック入力の場合
スティック入力の場合は、スティックの子のControlであるup、down、left、rightを2D Vector Compositeの各方向に指定すれば良いです。
例では、左スティックの各方向を割り当てることとします。
実行結果
アナログ入力のスティックでも8方向入力にスナップされていることを確認できました。
分かりやすさのため、スティックの状態を左下のUIに表示しています。
Processorを自作してスナップさせる
ここまで2D Vector Compositeにより2軸入力を8方向にスナップさせる方法を解説しました。
しかしながら、入力値のベクトルの大きさは必ず0または1にスナップされます。例えば、8方向にスナップさせるが、スティックの倒し具合(入力値の大きさ)も反映させたい場合には対応できません。
この場合、自作のProcessorによってスナップ処理を実装することで対処できます。
サンプルスクリプト
以下、2軸の入力値を8方向にスナップさせるProcessorの実装例です。オプションで入力値の大きさを0または1にスナップするか否かを設定できるようにしています。
上記をSnapDirectionProcessor.csという名前でUnityプロジェクトに保存すると、Snap Directionという名前のProcessorが使用可能になります。
方向をスナップさせるが大きさはそのままにする場合
ActionにBindingを追加し、該当するスティック入力などのControl Pathを指定し、Processors右の+アイコンからSnap Directionを選択して自作Processorを追加します。
入力値の大きさはそのまま維持したい場合は、Digital Normalizedのチェックを外します。
実行結果
スティック入力の大きさによって速さを変化させながら、8方向に向きをスナップさせられていることを確認できました。
デジタル入力にスナップさせる設定
ProcessorのDigital Normalizedにチェックを入れれば良いです。
実行結果
Vector 2 Compositeのように入力値の大きさが0と1にスナップされるようになりました。
スクリプトの説明
受け取った入力値の向きを8方向にスナップする処理は以下部分です。
8方向の向きの間隔は45度となるため、Mathf.Roundメソッドと除算を駆使して計算しています。
そして、入力値の大きさをVector2.magnituteプロパティから求め、必要なら0と1にスナップする処理を行っています。
閾値には、Input System Packageのボタン閾値の設定値を参照するようにしました。
これにより、角度(向き)と入力値の大きさが計算できたため、次の部分でベクトルを再計算します。
さいごに
2軸の入力を8方向にスナップする方法を解説しました。
Composite Bindingでも実現できますが、Processorを自作して適用するとより自由度の高いスナップ処理が実現できます。
Processorにすることで、あらゆる2軸入力に対して簡単にスナップ処理を適用することが可能になります。
何れの方法も、ゲームロジックと入力ロジックが分離されることにより、コードのメンテナンス性向上が期待できるでしょう。