【令和最新版】Unity6でInputSystemを使うチュートリアル

Unityの入力関係の処理を使うInputSystem。Unity6からは少し利用方法が変わっています。ここではシンプルな画像を移動させる方法をInputSystemで実装するところまでやってみたいと思います。

目次

InputSystemを使ってスプライトを動かす

ここでは2Dのプロジェクトを使ってInputSystemでスプライトを動かす処理を実装したいと思います。

プロジェクトの確認

解説を始める前に、Unityのバージョンやプロジェクトのテンプレートを確認しましょう。

  • Unityのバージョンは6以上
  • テンプレートは2D(Universal 2D)
    • 今回は説明用として2Dで行います
  • プロジェクト作成後、Assets直下にInputSystem_Actionsというアセットが出来ていることを確認
スライム

過去のバージョンではInputSystemを有効化したりする必要がありましたが、Unity6では最初からアクティブになっています

InputSystemのスクリプトを作成する

InputSystemはインスペクターで処理を行う方法と、アセットからスクリプトを生成してプログラムで動かす2種類があります。少し操作の慣れは必要ですが、個人的にはスクリプトを生成してからプログラムで動かす方が最終的には扱いやすいと思います。そのため今回はプログラムを利用するInputSystemでの実装をご紹介する予定です。

InputSystemをスクリプトで制御するには、アセットからC#スクリプトを生成する必要があります。といってもInputSystemのアセットを選択し、Generate C# Classにチェックを入れてApplyするだけです!

スライム

コードを生成する場所などをカスタマイズも出来ます。そのあたりについては追々・・・

プレイヤーを動かすコンポーネント作成

まずはプレイヤーを上下左右に移動させるためのスクリプトを作りましょう。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;

    private InputSystem_Actions inputActions;

    private void Awake()
    {
        inputActions = new InputSystem_Actions();
    }

    private void OnEnable()
    {
        inputActions.Enable();
    }

    private void OnDisable()
    {
        inputActions.Disable();
    }

    private void Update()
    {
        Vector2 input = inputActions.Player.Move.ReadValue<Vector2>();
        Vector3 move = new Vector3(input.x, input.y, 0);
        transform.Translate(move * Time.deltaTime * moveSpeed);
    }

}
  • InputSystemのインスタンスはEnable/Disableでアクティブ非アクティブの切り替えを行う必要がある
    • Awakeでインスタンスを作成(newしているところ)しています
    • OnEnable/OnDisableのタイミングで切り替えを行う
  • 移動している時のパラメータを取得する
    • Player.Move.ReadValue<Vector2>から入力があった時にパラメータを受け取ることが出来る

移動関連のアクションはMoveを利用します。MoveはAction Type:ValueでControl Type:Vector2が割り当てられています。これらの入力はプログラムで入力があった時、MoveのActionsに登録された入力を検出するとVector2の値が受け取れます。

攻撃したときのプログラムを追加

InputActionのPlayer.Actionを使って、攻撃した瞬間の入力を取ることが出来ます。Updateの中に攻撃(Attack)の瞬間にログが出るようにしています。

    private void Update()
    {
        Vector2 input = inputActions.Player.Move.ReadValue<Vector2>();
        Vector3 move = new Vector3(input.x, input.y, 0);
        transform.Translate(move * Time.deltaTime * moveSpeed);

        if (inputActions.Player.Attack.WasPressedThisFrame())
        {
            Debug.Log("Attack!");
        }
    }

AttackはAction Type:Buttonに分類されます。

ボタンは押し下げられたタイミング、押し続けられている、離されたタイミングの3つの状態を取ることが出来ます。

ボタン系の押された状態のメソッドタイミング
WasPressedThisFrame()現在のフレームでボタンが押されたかどうか
IsPressed()現在のボタンが押された状態か(長押し中もtrue)
WasReleasedThisFrame()現在のフレームでボタンが離されたかどうか

コールバックで入力を受け取る方法に変換

Updateの中での実装は直感的ですが、毎フレーム入力を監視するためパフォーマンスに若干の影響が見られます。そこで入力があったときだけ処理が実行されるコールバック方式もご紹介。ここではAttackのアクションをコールバック式に変えてみましょう。

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;

    private InputSystem_Actions inputActions;

    private void Awake()
    {
        inputActions = new InputSystem_Actions();
    }

    private void OnEnable()
    {
        inputActions.Enable();
        inputActions.Player.Attack.started += OnAttack;
    }

    private void OnDisable()
    {
        inputActions.Player.Attack.started -= OnAttack;
        inputActions.Disable();
    }

    private void OnAttack(InputAction.CallbackContext context)
    {
        Debug.Log("Attack performed!");
    }

    private void Update()
    {
        Vector2 input = inputActions.Player.Move.ReadValue<Vector2>();
        Vector3 move = new Vector3(input.x, input.y, 0);
        transform.Translate(move * Time.deltaTime * moveSpeed);
    }

}
  • アクションに対して3つのコールバックが用意されています
    • started:押された瞬間
    • performed:押されている最中
      • デジタルボタンの場合は1回のみ
      • ジョイスティックなどは変化のあるタイミングで都度
    • canceled:離された瞬間

Moveなど常に監視が必要なものにかんしてはコールバックではフォローしきれない場合があります。実装する場合は注意が必要です。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次