以前、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]ボタンをクリックします。

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

以下の文章はGoogle翻訳で日本語に直したものです。
「このプロジェクトは新しい入力システムパッケージを使用していますが、新しい入力システムのネイティブプラットフォームバックエンドがプレイヤー設定で有効になっていません。
これは、ネイティブデバイスからの入力が届かないことを意味します。
バックエンドを有効にしますか?
そうすることで、エディターが*再起動*され、古いUnityEngine.InputAPIが*無効*になります。」
InputSystem用のバックエンドを有効にすると、そのプロジェクトでは従来のUnityEngine.Inputが使用できなくなりますので既存のプロジェクトでは注意してください。
この設定はProject Settingsからいつでも変更可能です。
「Edit > Project Settings」でウィンドウを開き、「Player > Other Settings > Active Input Handling」から設定できます。

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から追加します。

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

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

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

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

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

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

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

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

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

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

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

ジャンプボタンを押された時に呼び出すスクリプトを作成しました。
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ボタンを押しました!");
}
}
これをこんな感じで設定して…

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

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