Input Systemでボタンが押されているかどうか判定する方法がよく分からないの…
やり方はいくつかあるけど、判定するだけならIsPressedメソッドを使えば良いわ。
Input Systemでボタンの押しっぱなしを判定する方法の紹介です。例えば、あるボタンを押している間だけUpdate内で何か処理したい場合など役立ちます。
押されているかどうかの判定は、次のように該当するActionのIsPressedメソッドを使えば簡単です。
Input Actionを使用せず、直接低レベルAPI(Keyboard、Gamepadクラスなど)を参照する場合などは、次のコードで押下状態を取得できます。
これによって、Updateイベント内などで毎フレームボタンが押されているかをチェックできるようになります。
また、少し面倒ではありますが、Actionのコールバックを利用して判定することも可能です。
本記事では、このようなボタンの押しっぱなし判定をする方法をいくつか紹介していきます。
- Unity 2021.3.2f1
- Input System 1.3.0
目次 非表示
前提条件
事前にInput Systemがインストールされ、有効化されているものとします。ここまでの手順が分からない方は、以下記事をご覧ください。
また、本記事ではPlayer Inputを使用した環境でボタンの押下状態を取得することを想定します。
Player Inputを使った入力値の取得方法については、以下記事をご覧ください。
InputActionのIsPressedメソッドを使う
InputActionインスタンスのIsPressedメソッドから押下状態を取得できます。
押されているならtrue、そうでなければfalseが返されます。
参考:Class InputAction| Input System | 1.3.0
サンプルスクリプト
Player Inputから攻撃Actionを取得し、攻撃ボタンの押下状態をログ出力するサンプルです。
このスクリプトをPressButtonExample.csという名前で保存し、適当なゲームオブジェクトにアタッチし、インスペクターよりPlayer InputとAction名を設定すると機能するようになります。
なお、Player InputのInput Actionを取得するためには、予めPlayer InputおよびActionアセットの設定を行っている必要があります。この手順が分からない方は、以下記事を参考にセットアップを済ませてください。
次の動画は、Player Inputのセットアップからスクリプトを適用するまでの例です。
実行結果
Actionを用いずに押下状態を取得する
Input Actionを使用せず、Keyboardなどの低レイヤーAPIを直接参照する場合は、該当するボタンのButtonControlインスタンスのisPressedプロパティから取得できます。
参考:Class ButtonControl| Input System | 1.3.0
サンプルスクリプト
キーボードの特定キーが押されているかを判定する例です。
上記スクリプトをKeyboardPressExample.csという名前で保存し、適当なゲームオブジェクトにアタッチすると機能します。必要に応じてKeyを設定してください。
実行結果
実行すると、押下状態がログ出力されます。
Actionのコールバック経由で押下状態を判定する
Player Input等のコールバックを用いて押下状態を判定する方法の紹介です。
前述の方法とは違い、フラグを保持しておく必要がある点で面倒ですが、InputActionを直接参照しなくても良いメリットもあります。
サンプルスクリプト
コールバック経由で押下状態をログ出力するサンプルです。Player Inputからコールバック呼び出しする場面を想定しています。Player InputのBehaviour項目にInvoke Unity Eventsが設定されていることを想定しています。
上記スクリプトをCallbackPressExample.csという名前で保存し、適当なゲームオブジェクトにアタッチし、Player Inputにイベントの登録を行うと機能するようになります。
次は、スクリプトのアタッチからFireイベントにOnFireメソッドを登録するまでの操作例です。
Player Inputからコールバック呼び出しする方法が分からない方は、以下記事をご覧ください。
実行結果は、先ほどの例と一緒のため、割愛させていただきます。
押下状態の遷移について
Input Systemでは、0と1の入力しか返さないボタンであっても、内部的にはfloat型の入力値として扱われます。
ボタンが押されたかどうかは、値の大きさが閾値(Press)以上になったかどうかで判定されます。2軸スティック入力(Vector2型)の場合は、ベクトルの大きさが閾値以上になったかどうかで判定されます。
また、押された状態から離された状態への遷移は、入力値の大きさが閾値Release以下になった時となります。
上記の一連の挙動は、内部的には次のような状態遷移になります。
ボタンが離されているときはWaiting、ボタンが押された瞬間(入力値がPress以上になった時)にPerformedに遷移します。ボタンが離される(入力値がRelease以下になった時)にはCanceledに遷移し、直後にWaitingに遷移します。
ボタンが閾値Press以上にならない限り、Performed(押された状態)にはなりません。
参考:Interactions | Input System | 1.3.0
また、閾値PressとReleaseは次のように値が決定されます。
- Press
- Input SettingsのDefault Button Press Point。ただしInteractionのPress Pointが設定されている場合はこちらが優先される
- Release
- Press × Input SettingsのButton Release Threshold。
Releaseの計算が少し複雑で、Pressとの掛け算をしている点に注意する必要があります。
例えば、Pressが0.5、Button Release Thresholdが0.75の場合、Releaseの値は0.5 × 0.75 = 0.375となります。
参考:Class InputSettings| Input System | 1.3.0
Interactionを適用した場合の挙動の違い
Interactionを適用した場合、Pressの値はInteraction側の設定値が優先されます。
参考:Class InputAction| Input System | 1.3.0
また、長押し(Hold)などのInteractionが指定された場合でも、押された瞬間に押された瞬間にIsPressedメソッドがtrueを返す挙動となることに注意する必要があります。
ただし、コールバックを受け取る実装をしている場合はこの限りではありません。理由はPerformedが呼ばれるまでフラグを見ない動作になっているためです。
さいごに
ボタンが押されているかどうかの判定は、Input ActionのIsPressedメソッドから知ることができます。
Interactionが適用されている場合は少し挙動が変化するので、使用の際は留意すると良いでしょう。