Unity_Lesson

「PlayerInput」コンポーネントで「Action」のアセットを管理してスクリプトから操作しやすくする


1.Player Inputコンポーネント

「Player Input」は、 Input Systemの入力を「仲介」する「コンポーネント」で、「Action」の入力をスクリプト側に通知します




2.Player Inputの利用

動かす対象をSphereとして書いていきます


動かす対象のオブジェクトにPlayer Inputコンポーネントをアタッチ。
アタッチすると、次のようなPlayer Inputプロパティがインスペクターに表示されます。


Actions項目にInput Actionアセットを指定。
(Input ActionはCreate Actions…ボタンから新規作成することも可能。) また、上の写真の中で特に重要な設定は「Actions」と「Behavior」になります。

「Behavior」の設定によって参照元のスクリプトのコードが異なります。
(後で、それぞれの設定における使い方について例を示しながら解説します。)




3.Behavior に Send Messages/Broadcast Messagesを設定した場合

Moveアクションの通知を受け取って、オブジェクトを移動させるサンプルスクリプト 下記スクリプトをプレイヤーオブジェクトにアタッチします。

Player InputコンポーネントのBehaviorをSend MessagesまたはBroadcast Messagesに設定。

Send Messagesを設定した場合は、Player Inputがアタッチされているオブジェクトにアタッチする必要があります。

Broadcast Messagesを設定した場合は、Player Inputがアタッチされているオブジェクトまたはその子オブジェクトにアタッチする必要があります。

SendMessageExample.cs


using UnityEngine;
using UnityEngine.InputSystem;

public class SendMessageExample : MonoBehaviour
{
    private Vector3 _velocity;

    // 通知を受け取るメソッド名は「On + Action名」である必要がある
    private void OnMove(InputValue value)
    {
        // MoveActionの入力値を取得
        var axis = value.Get<Vector2>();

        // 移動速度を保持
        _velocity = new Vector3(axis.x, 0, axis.y);
    }

    private void Update()
    {
        // オブジェクト移動
        transform.position += _velocity * Time.deltaTime;
    }
}

スクリプトについて

Player Inputから通知を受け取るためには、「On + Action名」という名前のメソッドを定義する必要があります。

例では、Moveという名前のAction通知を受け取るために、OnMoveメソッドを定義しています。

// 通知を受け取るメソッド名は「On + Action名」である必要がある
private void OnMove(InputValue value)
{
    // MoveActionの入力値を取得
    var axis = value.Get<Vector2>();

    // 移動速度を保持
    _velocity = new Vector3(axis.x, 0, axis.y);
}

引数は、入力値が格納されるInputValue型、 入力値はGetメソッドから取得できます。

通知は毎フレーム発行される訳ではないため、_velocity変数に速度を保持して、Updateイベント内で移動処理を行うようにしています。

private void Update()
{
    // オブジェクト移動
    transform.position += _velocity * Time.deltaTime;
}


4.Invoke Unity Eventsを設定した場合

プレイヤーオブジェクトにアタッチします。 Player InputコンポーネントのBehaviorにInvoke Unity Eventsを設定。

Events項目が出現するため、該当するイベントの+ボタンより通知を受け取るスクリプトのメソッドを指定して下さい


UnityEventExample.cs

    using UnityEngine;
    using UnityEngine.InputSystem;

    public class UnityEventExample : MonoBehaviour
    {
        private Vector3 _velocity;

        // 先ほどと違いメソッド名は何でもOKだが、 publicにする必要がある
        // Events項目が出現するため、該当するイベントの+ボタンより通知を受け取るスクリプトのメソッドを指定
        public void OnMove(InputAction.CallbackContext context)
        {
            // MoveActionの入力値を取得
            var axis = context.ReadValue<Vector2>();

            // 移動速度を保持
            _velocity = new Vector3(axis.x, 0, axis.y);
        }

        private void Update()
        {
            // オブジェクト移動
            transform.position += _velocity * Time.deltaTime;
        }
    }

実行結果は先ほどと同じです

スクリプトについて

通知を受け取るためのメソッドは次の形式。

public void OnMove(InputAction.CallbackContext context)

InputAction.CallbackContext型の引数を受け取る点が異なります。

入力値はReadValueメソッドから取得します。

var axis = context.ReadValue<Vector2>();


5.Invoke C Sharp Eventsを設定した場合

Input System全体でトリガーされるすべてのアクションをキャッチするための方法です。すべてのアクションを一つのコールバックで処理したい場合に便利。

通知を受け取るためのデリゲートは、onActionTriggeredプロパティより追加できます。

_playerInput.onActionTriggered += OnMove;

CSharpEventExample.cs


    using UnityEngine;
    using UnityEngine.InputSystem;

    [RequireComponent(typeof(PlayerInput))]
    public class CSharpEventExample : MonoBehaviour
    {
        private PlayerInput _playerInput;
        private Vector3 _velocity;

        private void Awake()
        {
            _playerInput = GetComponent<PlayerInput>();
        }

        private void OnEnable()
        {
            if (_playerInput == null) return;

            // デリゲート登録  onActionTriggeredプロパティに追加
            _playerInput.onActionTriggered += OnMove;
        }
        private void OnDisable()
        {
            if (_playerInput == null) return;

            // デリゲート登録解除
            _playerInput.onActionTriggered -= OnMove;
        }


        private void OnMove(InputAction.CallbackContext context)
        {
            // Move以外は処理しない
            if (context.action.name != "Move")
                return;

            // MoveActionの入力値を取得
            var axis = context.ReadValue<Vector2>();

            // 移動速度を保持
            _velocity = new Vector3(axis.x, 0, axis.y);
        }


        private void Update()
        {
            // オブジェクト移動
            transform.position += _velocity * Time.deltaTime;
        }
    }


特定のアクションに対して直接コールバックを設定

    using UnityEngine;
    using UnityEngine.InputSystem;

    public class InputHandler : MonoBehaviour
    {
        PlayerInput playerInput 
        InputAction jumpAction;

        private void Awake()
        {
            playerInput = GetComponent<PlayerInput>();
            jumpAction  = playerInput.actions["Jump"];
            jumpAction.performed += OnJump;
        }

        private void OnDestroy()
        {
            jumpAction.performed -= OnJump;
        }

        private void OnJump(InputAction.CallbackContext context)
        {
            // ジャンプアクションがトリガーされたときの処理
        }
    }