InputSystemでボタンが押され続けていることを検知したい ( IsPressedをつかえ
個人制作でInputSystemを使ってみようと思い試行錯誤
従来のInputから InputSystemへ乗り換えを考えていたとき、 「あるキーが押され続けているか」 という条件をどう取ろうか迷った。
if (Input.GetKey(KeyCode.LeftArrow))
{
moveDir = Vector2Int.left;
}
従来であれば Input.GetKey でtrueが返ってくるコードだが InputSystem では....
ちなみに、動きだけを表すInputControlsを作成して試している。
キーボードの左キーを押したときはもちろんの事、ActionはButtonにしてUI上の移動ボタンが押されたときにも反応できるようにしてます。
とりあえずリファレンスを確認 (折角?なので現時点で最新のv1.1.0-preview.3で実行しています) Polling Actionsという場所。
Actions | Input System | 1.1.0-preview.3
以下の2つ例で書かれている
public InputAction moveAction; public float moveSpeed = 10.0f; public Vector2 position; void Start() { moveAction.Enable(); } void Update() { var moveDirection = moveAction.ReadValue<Vector2>(); position += moveDirection * moveSpeed * Time.deltaTime; }
private InputAction action; void Start() { // Set up an action that triggers when the A button is // held for 1 second. action = new InputAction( type: InputActionType.Button, binding: "<Gamepad>/buttonSouth", interactions: "hold(duration=1)"); action.Enable(); } void Update() { if (action.WasPerformedThisFrame()) Debug.Log("A button on gamepad was held for one second"); }
まず、 ReadValue<T>
方式ですが、 これで取得できました (目標達成
コードは以下
f (move.Left.ReadValue<float>() > 0f) { ... }
このReadValue
float というのが非常に引っかかる!
(ちなみに ReadValueInvalidOperationException
が出ます。)
なぜ float だと ReadValue で取得できるかというと Unity のInpusSystemのGithubからButtonWithOneModifierを参照すると float の InputBindinfComposite を継承しているから
一応これで目的は達成できそうですが他にもみていきます。
次のサンプルのWasPerformedThisFrame はその名の通り 「このフレームで押されたか」 という、押されたとき一回だけのイベントが取れそう
つまり今回の「押され続けているか」とは違う
リファレンスの少し下を見ると InputActon.IsPressed() というメソッドを見つけた。
リポジトリ上でみてもこれ使えそう
(InputSystem周りコメントがぎっしり!サンプルも付いてるし。正直ありがたい)
ということで、リファレンス通り InputControl に対して単純に IsPressed メソッドを使用すれば「押されているか」というイベントがとれました。
if (move.Left.IsPressed()) { // 左キーor左ボタンが押されている }
v1.1 以前はこの IsPressed メソッドはなかった気がする。
以前調べたとき、クラス内では存在していたが公開されていないので悩んだ記憶があります。
ReadValue