【Unity】出来るだけ簡単にNew Input Systemを使いたい
新しいInput Systemは少し面倒くさい
新しいInput Systemですが、正直な意見として面倒くさいというのがあります。アクションにキーを割り振るという思想は非常に理にかなっていますし、応用で色々出来るのは悪くないとは思いますが、以前のInput Managerのようにすぐ使えないのはすごくマイナスです。
そこで、サクッと使える使い方について確認してみます。
PlayerInputを使用する
サクッとプレイヤーの入力を取得するアプローチとしてPlayerInput
コンポーネントがあります。このコンポーネントを使えば面倒くさい作業が多少楽になります。
- WASDやGamepadに対応した移動等を含むInputActionsを生成してくれる。
- SendMessageで該当のメソッドを呼び出してくれる
- InputSystemの初期化
特にInputActionsの生成は面倒くさい項目の一つなので、とりあえず動くものがサクッと手に入るのは非常に楽でよいです。ここで生成するInputActionsのアクションマップには「WASDキーやGamePadでの移動」「マウス操作や右スティックの視点移動」「マウスクリックやゲームパッドに反応する射撃」の操作が含まれます。
なおこの記事はUnity 2019.2 × InputSystem 1.0 の組み合わせで作成されています。
PlayerInputの利用手順
- 入力を受け付けたいオブジェクトに
PlayerInput
コンポーネントを登録。 - PlayerInputの
CreateActions
を押して、アクションマップを生成。 - PlayerInputの
DefaultMap
をPlayer
に変更。 - PlayerInputの
Behaviourを
SendMessage`に変更
あとは下のコードを記述してPlayerInputをアタッチしたGameObjectに追加します。入力はそのまま使用せず、いったんフィールドにキャッシュして使用します。これは現状InputSystemが変化した値を検出するためです。
なおSendMessageと聞いて顔をしかめるかもしれませんが、今の端末性能的に一フレーム数回のSendMessageなど誤差のようなものです。
using UnityEngine; using UnityEngine.InputSystem; public class Example: MonoBehaviour { public Vector2 move { get; private set; } public Vector2 look { get; private set; } public bool fire { get; private set; } public void OnMove(InputValue value) => move = value.Get<Vector2>(); public void OnLook(InputValue value) => look = value.Get<Vector2>(); public void OnFire(InputValue value) => fire = value.Get<float>() > 0; void Update() { Debug.Log($"Move[{move}], Look[{look}], Fire[{fire}]"); } }
もしポーリングするスタイルで使用したい場合、下のような記述になります。playerInput.actions["アクション名"]
でアクションの情報が取得できるので、あとはReadValueで現在の状態を取得していく感じです。
using UnityEngine; using UnityEngine.InputSystem; public class Example: MonoBehaviour { InputAction move, look, fire; void Start() { var playerInput = GetComponent<PlayerInput>(); move = playerInput.actions["Move"]; look = playerInput.actions["Look"]; fire = playerInput.actions["Fire"]; } void Update() { var m = move.ReadValue<Vector2>(); var l = look.ReadValue<Vector2>(); var f = fire.ReadValue<float>() > 0; Debug.Log($"Move {m}, Look {l}, Fire {f}"); } }
なおPlayerInputにはUnity 2019.3 b7だと正常に動作しましたUnityEvent
を受け取るという機能もありますが、これはUnity 2019.3では動作しませんでした。同梱のサンプルも動作しないのでバグと思われます(2019.2では動作します)。
キー入力やゲームパッドの取得
デバッグ目的等でサクッと特定のキー入力を使用したい場合、下のような形で取得出来ます。InputActionのように入力をアクション単位で抽象化出来ないので、サクッと使える反面、複数の環境に対応させようと思ったら少し面倒くさいことになるかもしれません。
// マウスの左クリックを検出 Mouse.current.leftButton.wasPressedThisFrame; // キーボードのスペースキーを検出 Keyboard.current.spaceKey.wasPressedThisFrame; // ゲームパッドの左スティックを検出 Gamepad.current.leftStick.ReadValue();