【Unity】Inputに代わる新しい入力システム、「InputSystem」とは?

Unity-新しい入力システム?InputSystemについて紹介! Unity
スポンサーリンク

以前、UnityでUnityEngine.Inputに用意された関数を使ってマウスやキーボードでの入力を判定する方法についての記事を書きました。

今まではUnityEngine.Inputを使った方法が一般的だったと思いますが、なんとUnityにはこの代わりとして使用できる入力システムが用意されていました。
それがInputSystemです。

正直言うと私はこのシステムの存在を知りませんでした。
いつも実装方法知りたいときは「Unity 移動」とかで検索していたのですがこれだとInputSystemについての記事が上の方に出てこないんですよね。
なのでInputについて調べている時にInputSystemのことを知って「なんか便利そうなのあるじゃん…」ってなってました。

というわけでこの記事ではInputSystemのインストールと基本の使い方について紹介します。

この記事での使用バージョンは以下の通りです。
Unity:2022.1.1f1
InputSystem:1.3.0

InputSystemとは?

InputSystemはUnityのパッケージとして提供されています。
公式マニュアルによると、InputSystemではあらゆる種類の入力デバイスを使用してUnityコンテンツをコントロールするシステムを実現できるそうです。
従来のInputよりも強力で柔軟であるとも謳われています。

InputSystemのインストール方法

早速InputSystemをインストールしてみます。
Unityを起動したら「Window > Package Manager」を選択してPackage Managerを表示します。
左上のPackagesで「Unity Registry」を選択し、InputSystemを探して[Install]ボタンをクリックします。

PackageManagerでInputSystemをインストールする画像
Input Systemが出てこない場合は左上が「Packages: Unity Registry」になっているか確認してください

インストールが進むと英語で書かれた警告ダイアログが出てきます。
InputSystem用のネイティブプラットフォームバックエンドを有効にするかどうか聞かれます。
[Yes]をクリックするとエディターが再起動します。

InputSystemインストール後の警告ダイアログの画像
今回はYesを押して進めます

以下の文章はGoogle翻訳で日本語に直したものです。
「このプロジェクトは新しい入力システムパッケージを使用していますが、新しい入力システムのネイティブプラットフォームバックエンドがプレイヤー設定で有効になっていません。
これは、ネイティブデバイスからの入力が届かないことを意味します。
バックエンドを有効にしますか?
そうすることで、エディターが*再起動*され、古いUnityEngine.InputAPIが*無効*になります。」

InputSystem用のバックエンドを有効にすると、そのプロジェクトでは従来のUnityEngine.Inputが使用できなくなりますので既存のプロジェクトでは注意してください。
この設定はProject Settingsからいつでも変更可能です。
「Edit > Project Settings」でウィンドウを開き、「Player > Other Settings > Active Input Handling」から設定できます。

ProjectSettingsの入力システムのバックエンド設定の画像
一番上(Old)が従来のInputManager、二番目(New)がInputSystem、三番目(Both)は両方とも有効にする設定です

InputSystemの使用方法

1.デバイスの状態を取得してみる

InputSystemの「Gamepad.current」を使うと現在接続しているゲームパッドの入力状態を取得できます。
以下は接続したゲームパッド(ついでにマウスとキーボード)の入力状態を取得して画面に表示するスクリプトの例です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;  // ←これの追加が必要
public class TestScript : MonoBehaviour
{
    void OnGUI()
    {
        // ゲームパッドが接続されていなければnull
        if (Gamepad.current == null) return;
        // ゲームパッド
        // スティック
        GUILayout.Label("左スティック:" + Gamepad.current.leftStick.ReadValue());
        GUILayout.Label("右スティック:" + Gamepad.current.rightStick.ReadValue());
        GUILayout.Label("左スティック押し込み:" + Gamepad.current.leftStickButton.ReadValue());
        GUILayout.Label("右スティック押し込み:" + Gamepad.current.rightStickButton.ReadValue());
        // LR
        GUILayout.Label("ZL:" + Gamepad.current.leftTrigger.ReadValue());
        GUILayout.Label("ZR:" + Gamepad.current.rightTrigger.ReadValue());
        GUILayout.Label("L:" + Gamepad.current.leftShoulder.ReadValue());
        GUILayout.Label("R:" + Gamepad.current.rightShoulder.ReadValue());
        // 十字キー
        GUILayout.Label("十字キー:" + Gamepad.current.dpad.ReadValue());
        // ボタン
        GUILayout.Label("上ボタン:" + Gamepad.current.buttonNorth.isPressed);
        GUILayout.Label("下ボタン:" + Gamepad.current.buttonSouth.isPressed);
        GUILayout.Label("左ボタン:" + Gamepad.current.buttonWest.isPressed);
        GUILayout.Label("右ボタン:" + Gamepad.current.buttonEast.isPressed);
        // a b x y
        GUILayout.Label("Aボタン:" + Gamepad.current.aButton.isPressed);
        GUILayout.Label("Bボタン:" + Gamepad.current.bButton.isPressed);
        GUILayout.Label("Xボタン:" + Gamepad.current.xButton.isPressed);
        GUILayout.Label("Yボタン:" + Gamepad.current.yButton.isPressed);
        // ○△×□
        GUILayout.Label("○ボタン:" + Gamepad.current.circleButton.isPressed);
        GUILayout.Label("△ボタン:" + Gamepad.current.triangleButton.isPressed);
        GUILayout.Label("×ボタン:" + Gamepad.current.crossButton.isPressed);
        GUILayout.Label("□ボタン:" + Gamepad.current.squareButton.isPressed);
        // スタート・セレクト
        GUILayout.Label("スタートボタン:" + Gamepad.current.startButton.ReadValue());
        GUILayout.Label("セレクトボタン:" + Gamepad.current.selectButton.ReadValue());
        // マウス
        GUILayout.Label("左クリック:" + Mouse.current.leftButton.isPressed);
        GUILayout.Label("右クリック:" + Mouse.current.rightButton.isPressed);
        GUILayout.Label("マウスホイールクリック:" + Mouse.current.middleButton.isPressed);
        // キーボード
        GUILayout.Label("スペースキー:" + Keyboard.current.spaceKey.isPressed);
        GUILayout.Label("Escキー:" + Keyboard.current.escapeKey.isPressed);
        GUILayout.Label("Aキー:" + Keyboard.current.aKey.isPressed);
    }
}

空のGameObjectを作成してスクリプトをアタッチし、ゲームパッドを接続した状態で実行してみます。
ボタンを押すと対応したボタンの状態が「true」になります。
スティックや十字キーの場合は入力している方向に-1~1の値が表示されます。
もちろんキーボードやマウスの入力にも反応しました。

ゲームパッドの状態を取得するスクリプトを実行した画像
ゲームパッドを接続していない場合は文字は表示されません

しかもこれ、最初はXBOXコントローラーで動かしていたのですが途中からPS4のコントローラーに変えてみてもちゃんと動きました。
実行したままコントローラーを入れ替えても問題ないようです。

「buttonNorth」「buttonSouth」「buttonWest」「buttonEast」は例では上下左右と表しましたが、実際の方向は以下のようになっています。
・buttonNorth:XBOXのYボタン、PS4の△ボタン
・buttonSouth:XBOXのAボタン、PS4の×ボタン
・buttonWest:XBOXのXボタン、PS4の□ボタン
・buttonEast:XBOXのBボタン、PS4の○ボタン
詳しくは公式マニュアルのClass Gamepadを参照してください。

2.Actionから入力を取得する

次は「Fire」などのActionにキーを割り当てて入力を取得する方法です。
これがInputSystemのメインの使い方になります。

①PlayerInputコンポーネントをアタッチ

Actionを使うにはまずオブジェクトにPlayer Inputコンポーネントをアタッチします。
InspectorウィンドウのAdd Componentから追加します。

PlayerInputコンポーネントをオブジェクトにアタッチする画像
Player Inputを選択します
②inputactionsファイルを作成

アタッチしたら[Create Actions]をクリックします。
ダイアログが表示されるので「.inputactions」ファイルの名前と保存先を指定します。

PlayerInputのCreateActionsの画像
Create Actionsを選択します

保存するとActionsウィンドウが表示され、Player InputのActionsにファイルがセットされます。

Actions設定ウィンドウの画像
「Actions」という名前で作成しました

Actionsウィンドウでは初期状態ですでにいくつかActionが設定されています。
PlayerのMoveというActionを見てみると、ゲームパッドやキーボードでの操作がバインドされています。
ウィンドウでキーを割り当ててスクリプト側ではそのActionを呼び出すだけでいいので、今までInputでやっていたことと同じような扱いができます。

PlayerのMoveActionの設定画像
ゲームパッド、キーボードなどが設定されています
③Actionの追加

Actionを追加するには、Actionsの右側にある+をクリックします。
Jumpという名前のActionを追加してみます。

Actionを追加する画像
New Actionが追加されました

追加したActionにはバインドがひとつ用意されています。
さらにバインドを追加する場合は、Action名の右側の+をクリックして追加できます。
今回はとりあえず一つ割り当てれば十分なのでデフォルトのままで進めます。

Jumpにバインドを追加する画像
バインドを複数追加できます

Actionに使用するコントローラーにチェックをいれます。

コントローラーの設定画像
チェックを入れておかないと設定しても動きません

Pathの右にあるリストから割り当てるキーを選択できます。

キー割り当ての画像
ボタンの一覧がでてきます

割り当てるボタンをわざわざ探さなくても1発で見つける方法があります。
なんと左上にある[Listen]ボタンをクリックした後に設定したいボタンを押すだけで、該当するボタンを表示してくれます。

Listenを使ってボタンを検索している画像
ゲームパッドもキーボードもこの機能ですぐ設定できます

設定した後は[Save Asset]をクリックして忘れずに保存しておきましょう。

Action設定を保存する画像
セーブ大事
④Actionを実際に操作する

Actionの定義ができたら応答を設定しましょう。
Player InputのBehaviorのリストから選択します。
今回は「Invoke Unity Events」を使用します。

応答設定の画像
Invoke Unity Eventsの場合はUnityUIと同じように使用できます

Behaviorの下にEventsが出てくるので展開すると、各Actionごとにイベントが登録できるようになっています。

Eventsを展開した画像
UIのボタンクリックなどと同じですね

ジャンプボタンを押された時に呼び出すスクリプトを作成しました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
    public void OnJump(InputAction.CallbackContext context)
    {
        Debug.Log("Jumpボタンを押しました!");
    }
}

これをこんな感じで設定して…

Jump処理の設定画像
OnJump関数を呼ぶように設定

実行してゲームパッドで割り当てたボタンを押してみるとコンソールに出力されました。

OnJump実行結果の画像
ちゃんとOnJumpが呼び出されました

まとめ:InputSystemを使うにはActionにキーを割り当てればOK!後はActionごとに呼び出す関数を書くだけ!

Action作ってキーを割り当てるだけで設定が完了するのでとても楽に実装できましたね。
特にListen使ってボタン押すだけで対応のキーを探してくれるのがめちゃくちゃ便利です。
それぞれのActionに応じて関数作ればいいので、コードもまとめられてすっきりしそうです♪

コメント

タイトルとURLをコピーしました