Unity_Lesson

1.「Action」をMapというアセットとして管理する

「Action」たちを管理しやすいようにMapという形をとります。


「PlayerMap(Player階層)のMoveというActionを使って!」などとスクリプトに指示を出す形です。


Actionの中には、どの入力デバイスを参照するかといったキーバインド情報(Binding)が格納されており、マウスやキーボードやGamepadなどをスクリプトで判別しなくても、Actionに設定されたデバイスからの入力を受け取ることができます。



2.Input Actionsアセットを作成し、使ってみよう

メニューからAssets > Create > Input Actionsの順に選択


GameInputsなど、適当な名前をつけてInput Actionsアセットを作成します


作成したInput Actionsアセットをダブルクリックし、Input Actionsの編集ウィンドウを開きます


左上のActions Maps右の+ボタンをクリックし、Action Map名(例として「Player」)を入力。


例として、移動の「Action」として「Move」と、ジャンプの「Action」として「Jump」を設定してみます。


新しいActionの追加は、Actions右上の+ボタンから行います。「Jump」を追加して下さい


次は、作成したそれぞれの「Action」の挙動の設定です
例えば、



・移動操作「Move」の設定例
Action > Action Type項目を「Value」
Action > Control Type項目を「Vector2」に設定


・ジャンプ操作「Jump」の設定例
Action > Action Type項目は「Button」


作成した「Action」にキーバインド情報を設定していきます


BindingはActionの右にある+アイコンから複数追加できます


・移動操作の設定例
例として、ゲームパッドの左スティック入力は、
Binding Properties > Binding > Path項目に、Gamepad > LeftStickで設定
もしくは、
Path選択リストの左のListenボタンをクリックしてから、実際にコントローラーを触って入力すると、該当するパスが即座に一覧出てくるので、それを選択してください


さらにキーボード入力も追加してみましょう
Action右の+アイコンからAdd Up\Down\Left\Right Compositeを選択


4方向それぞれに対して、パスを設定してください


・ジャンプ操作の設定例
ジャンプに関しても同じ要領です


※忘れずにSave Assetボタンをクリックして設定を保存(Auto-Saveにチェックでも可)



3.Input Actionsアセットの使用

それでは実際に使用してみましょう。
試しに、シーン上に配置されたボールを操作できるようにしていきます


Input Actionのソースコードを生成していきます。
作成したInput Actionsアセットを選択し、Generate C# Classにチェックを入れます。
すると、


保存に成功すると、指定したパスにスクリプトが追加されます。


先述のInput Actionクラスから入力を取得し、ボールを操作するスクリプトを実装します。
PlayerMover.csなどとスクリプトを作成し、ボールを動かしてみて下さい。

PlayerMover.cs

    using System;
    using UnityEngine;
    using UnityEngine.InputSystem;

    [RequireComponent(typeof(Rigidbody))]
    public class PlayerMover : MonoBehaviour
    {
        [SerializeField] private float _moveForce = 5;
        [SerializeField] private float _jumpForce = 5;

        private Rigidbody _rigidbody;
        private GameInputs _gameInputs;
        private Vector2 _moveInputValue;

        private void Awake()
        {
            _rigidbody = GetComponent<Rigidbody>();
     
            _gameInputs = new GameInputs();// Actionスクリプトのインスタンス生成

            // Actionイベント登録
            _gameInputs.Player.Move.started   += OnMove;
            _gameInputs.Player.Move.performed += OnMove;
            _gameInputs.Player.Move.canceled  += OnMove;
            _gameInputs.Player.Jump.performed += OnJump;

            // Input Actionを機能させるために、有効化
            _gameInputs.Enable();
        }

        private void OnDestroy()
        {
            // 自身でインスタンス化したActionクラスはIDisposableを実装しているので、
            // 必ずDisposeする必要がある
            _gameInputs?.Dispose();
        }

        private void OnMove(InputAction.CallbackContext context)
        {
            // Moveアクションの入力取得
            _moveInputValue = context.ReadValue<Vector2>();
        }

        private void OnJump(InputAction.CallbackContext context)
        {
            // ジャンプする力を与える
            _rigidbody.AddForce(Vector3.up * _jumpForce, ForceMode.Impulse);
        }

        private void FixedUpdate()
        {
            // 移動方向の力を与える
            _rigidbody.AddForce(new Vector3(
                _moveInputValue.x,
                0,
                _moveInputValue.y
            ) * _moveForce);
        }
    }

スクリプトについて

Input Actionの機能を参照するために、次の名前空間をusingします

using UnityEngine.InputSystem;

そして、Input Actionの初期化を行います。
インスタンスを生成してから、各種Actionにイベントを登録しています。設定が終わったら、Enable()メソッドでInput Actionを動作させる必要があります。(Enable()メソッド呼び出しを忘れると、Input Actionが機能せず入力値が取得できなくなるため注意。)

// Input Actionインスタンス生成
_gameInputs = new GameInputs();

// Actionイベント登録
_gameInputs.Player.Move.started += OnMove;
_gameInputs.Player.Move.performed += OnMove;
_gameInputs.Player.Move.canceled += OnMove;
_gameInputs.Player.Jump.performed += OnJump;

// Input Actionを機能させるためには、
// 有効化する必要がある
_gameInputs.Enable();

各種Actionのコールバックは次のような形式になります。
引数contextのReadValue()メソッドから入力情報を取得できます。2つ目のジャンプイベントのほうは、ボタンが押された瞬間のみ呼び出されるため、力を与える処理のみ記述しています。
Input Systemは設定次第でUpdateやFixedUpdate、その他任意のタイミングで呼び出される可能性があります。そのため、OnMoveコールバック内では入力値の保存のみ行い、別途FixedUpdateイベントで参照する形をとっています。

private void OnMove(InputAction.CallbackContext context)
{
    // Moveアクションの入力取得
    _moveInputValue = context.ReadValue<Vector2>();
}

private void OnJump(InputAction.CallbackContext context)
{
    // ジャンプする力を与える
    _rigidbody.AddForce(Vector3.up * _jumpForce, ForceMode.Impulse);
}