C++幼女先輩

プログラミング成分多め

【UNITY 2020.2.6f1】New Input System(1.0.2)を使ってみる

New Input Systemについて

新しい入力が出来ました
引き続き旧来の入力方法を使う事が出来ますが
これを期にInputSystemを覚えようと思います

旧来の方法

旧来のInputではInputManagerのAxes
下記のように入力を取得していました

h = Input.GetAxis("Horizontal");
v = Input.GetAxis("Vertical");
j = Input.GetButton("Jump");

New Input Systemを使う

細かいことはほかの人のブログで・・

まず、PackageManagerからInputSystemをInstallします
メニューのWindows PackageManagerから PackageManagerを起動し
左上のリストから、Packages: Unity Registryを選び、 Input Systemを検索
今回は最新の1.0.2 を選択しInstallします
ちなみに、Samplesからサンプルのパッケージをインストールする事もできます

f:id:murasame-labo:20210306183011p:plain

インストールを終えたら、New Input Systemを使うように変更します
ProjectSettingsのPlayerSettingから、Active Input Handlingを Input System Package(New)に変更します
そうするとUNITYエディタが再起動します

f:id:murasame-labo:20210306183340p:plain

これで、InputSystemが有効になり、旧来の入力が効かなくなります

InputSystemを設定する

InputSystemの設定は少し面倒です

まず、右クリックから Create-InputActionを行い、InputActionAssetを作成する
ダブルクリックを行い、ActionMaps、Actionsと、入力キーのぶんだけ作成します
例えば、移動はxzの2軸なのでMoveという名前で Vector2で作成します
キーボードだとWASDと矢印キーにそれぞれUp、Down、Left、Rightを設定
他にもGamePad、Touch、Joystick、XRも設定する
FireはActionTypeはButtonで、マウス左クリックやゲームパッドの右トリガーなどに割り当てる
そのほか使うボタンを登録します

f:id:murasame-labo:20210306184209p:plain

そしてそれを登録すればよいのですが
めんどくさいので UNITYが用意したものを使います

PlayerInputコンポーネント

動かしたいオブジェクトに、AddComponentから PlayerInput を追加します
すでに基本的なキー入力のAssetが設定されているので、非常に手抜きができます
DefaultMapをPlayerにし、BehaviorをSendMessagesにする

f:id:murasame-labo:20210306190525p:plain

実際に値を取得する時は下記のようになる

    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;
    public void OnJump(InputValue value) => jump = value.Get<float>() > 0;

このように、Onアクション名 というCallbackで指定したアクションが取れます
コールバックで処理するのが面倒だなー、従来のようなポーリングで取りたい場合は
上記のようにコールバックで値を変数に保存してもいいですが
PlayerInputには、ポーリングをするインタフェースも用意されてます

    // InputActionを定義
    Private InputAction move, jump;

    void Start()
    {
        PlayerInput playerInput = GetComponent<PlayerInput>();

        // 各アクションの参照を取得
        move = playerInput.actions["Move"];
        jump = playerInput.actions["Jump"];
    }

    void Update()
    {
        Vector2 m = move.ReadValue<Vector2>();  // 2軸の値はVector2で取得
        bool j = jump.ReadValue<float>() > 0;  // bool値はfloat値で 0より大きいかで判断する
    {

これで、ポーリングでもイベントでも取得が可能です