土鍋で雑多煮

UnityでXR・ゲーム開発をしています。学んだことや備忘録、趣味の記録などを書いていきます。

InputActionの個人的ベストな使い方 ~InputActionProperty~

どうも、土鍋です。
この記事はUT-virtual アドベントカレンダー22日目の記事です。

皆さん、Input System使っていますか?

その中でもInput Actionを利用することで複数デバイスに対応しやすくなりますので、最近は積極的に利用しています。

しかし、InputActionの使い方には複数手法があり、初心者にはとっつきづらいと思います。そこで今回は個人的にベストな使い方をご紹介します。

InputActionの使い方

Input Actionについて調べるとPlayer Inputコンポーネントを使用する方法がまず出てきます。

using UnityEngine;
using UnityEngine.InputSystem;

public class Player : MonoBehaviour
{
   Vector3 move;

   public void OnMove(InputAction.CallbackContext context)
   {
       move = context.ReadValue<Vector2>();
   }

   public void OnFire(InputAction.CallbackContext context)
   {
       if (context.phase == InputActionPhase.Performed)
       {
           Debug.Log("Fire");
       }
   }

   void Update()
   {
       const float Speed = 1f;
       transform.Translate(move * Speed * Time.deltaTime);
   }
}


Unityの新入力システム・Input Systemを使おう – Unity for Proから引用

この方法はたしかにインスペクターから設定でき、初心者でもとっつきやすいですが、拡張性が低く、ある程度コードを書けるようになってくると使いづらいと思います。

そこで、InputActionアセットからクラスを生成する方法もあります。

using UnityEngine;

public class Player : MonoBehaviour
{
   TestInputActions testInputActions;

   void Awake()
   {
       testInputActions = new TestInputActions();
       testInputActions.Enable();
       testInputActions.Player.Fire.performed += context => Debug.Log("Fire");
   }

   void Update()
   {
       const float Speed = 1f;

       var direction = testInputActions.Player.Move.ReadValue<Vector2>();
       transform.Translate(direction * Speed * Time.deltaTime);
   }
}

Unityの新入力システム・Input Systemを使おう – Unity for Proから引用

この方法ではスクリプトだけで完結しますが、ActionごとにC#スクリプトを生成する必要がありますし、必要なActionの使用の書き方がなかなか面倒だと思います(個人的感想)

InputActionPropertyを使用する方法

なんか、どの方法も使い勝手悪いな~と思っていたのですが...

XR Interaction toolkitのInput Actionの使用方法がかなり使い勝手が良かったので、最近は真似して書いています。

その方法とはInputActionPropertyを使用する方法です。

[SerializeField]
private InputActionProperty playerMoveInput;

private void Awake()
{
    playerMoveInput.action.Enable();
}

void Update()
{
    move = playerMoveInput.action.ReadValue<float>()
    transform.Translate(move * Speed * Time.deltaTime);
}

このように書くとインスペクターからこのように設定できます。

だいぶ直感的ですね。

この方法であれば、特定のActionだけをインスペクターからセットできますし、コード的にもかなり簡潔に理解しやすく書くことができます。

調べたときになかなかこの方法にたどり着かなかったので、今回記事を書きました。どなたかの参考になれば嬉しいです。