Unityの新しい入力システムInputSystemを使ってみる

今回はUnityの新しい入力システムであるInputSystemを使ってみたいと思います。

現時点(2019/11/13)ではまだプレビュー版ですが、今後はInputSystemが使われ、おそらく以前から使用しているInputManagerが廃止されていくような感じですね。

いつInputManagerが使えなくなってもいいようにInputSystemを使えるようにしておくことにしました。

InputSystemを使用するにはUnity 2019.1+および.NET 4ランタイムが必要です。

スポンサーリンク

InputSystemのインストール

UnityのメニューのWindowからPackage Managerを選択し、開いたウインドウのAdvancedの部分を押してShow preview packagesを選択します。

Show preview packagesにチェックを入れるとプレビュー版の機能も表示されます。

Input Systemを選択し、Installボタンを押してインストールします。

UnityのInputSystemのインストール

これでInputSystemのインストールが出来ました。

InputSystemを使えるように設定する

InputSystemをインストールすると既に使える状態になりますが、後から以前のInputManagerを使った操作とInputSystemのどちらを使うか、または両方使うかの設定をすることができます。

UnityメニューのEdit→Project Settingsを選択し、Playerを選択し、Active Input Handlingで切り替えが出来ます。

UnityのInputManagerとInputSystemの切り替え設定

設定を切り替えて反映させる為にUnityが再起動されます。

ただ現時点では、PlayerのActive Input HandlingをInput System(Preview)もしくはBothを選択するとUIのText等に直接日本語入力が出来ないです(以前のUnityでも同様の現象があったような?)。

スクリプトから出力もしくはコピーしたやつを貼り付ける事は出来るようです。

正式版が出るころには出来るようになっているでしょうか。

InputSystemの設定ファイルの作成

次にそのままInput System Packageを選択し、Create settings assetボタンを押し設定ファイルを作成します。

UnityのInputSystemPackageの設定ファイルを作成

するとAssetフォルダに設定ファイルが作成され、InputSystemPackageを選択した時の設定ファイルとされます。

UnityのInputSystemPackageの設定

右上の歯車を押すと他の設定ファイルと切り替えたり、新しい設定ファイルを作成する事が出来ます。

Update Modeは入力システムの処理をするタイミングのイベントのモードです。

Process Events In Dynamic Updateは現在のフレームレートでイベントが発生します。
Process Events In Fixed Updateは固定フレームレートでイベントが発生します。
Process Events In ManuallyはスクリプトからInputSystem.Updateメソッドを呼んで自分でイベントを発生させます。

Filter Noise on currentはスクリプトで.currentプロパティを使用する場合にチェックを入れます。

例えば新しい入力があった場合に、現在のゲームパッドを取得する場合はGamepad.currentで取得できますが、PS4コントローラー等はジャイロ機能の影響でノイズが発生する為に一定の入力値が得られてしまうのでここでチェックを入れてノイズをカットするようです。

スクリプトで.currentプロパティを使わない場合はチェックは入れない方がいいみたいです。

Compensate Orientationはセンサーによって得られる回転値をZ軸を中心に回転させます。
Default Deadzone Minはプロセッサで値が明示的にされていない時の代替で使用する最小値です。この値より下の入力値の場合は入力を無視します。
Default Deadzone Maxはプロセッサで値が明示的にされていない時の代替で使用する最大値です。この値より上の入力値の場合は入力を無視します。
Default Button Press Pointはボタンが「押された」と判定するまでに押し続ける必要がある範囲です。
Default Tap Timeはタップと認識する時間。押してから離すまでの時間
Default Slow Tap Timeはスロータップとして認識する時間。押してから離すまでの時間
Default Hold Timeはアクションを保持する時間。次のアクションまでの保留時間ですかね?
Tap Radiusはタップ(の指?)の半径
MultiTap Delay Timeはマルチタップと認識する為の間隔時間。

Supported DevicesはInputSystemで認識出来るデバイスをプロジェクト毎に限定したい時に使用します。

全てのデバイスの入力を受け付ける場合はリストには何も登録せず、例えばゲームパッドだけの入力を受け付ける時はリストにGamepadだけを登録します。

ゲームパッドだけの設定にするとUnityエディター上でもゲームパッドの操作に限定されて困る場合はUnityメニューのWindowからAnalysisを選択しInput Debuggerウインドウを開きます。

Input DebuggerのOptionsメニューからAdd Devices Not Listed in ‘Supported Devices’を選択します。

ここら辺はドキュメントに記載があるので詳しい所はそちらを参照してみてください。

Input settings | Input System | 1.0.0

ゲームパッドやキーボード、マウスの入力を直接取得してみる

InputSystemのインストールと設定が出来たので、次はゲームパッドやキーボード、マウスの入力をスクリプトで直接取得してみましょう。

InputManagerの時のInput.GetKeyDown(“space”)のように直接キーの指定をして取得するのと同じ感じです。

新しくDirectInputTestスクリプトを作成しMainCamera等のゲームオブジェクトに取り付けます。

InputSystem系のクラスはUnityEngine.InputSystemパッケージにありますのでusingディレクティブで指定します。

またスクリプトで使用しているKeyControlクラスはUnityEngine.InputSystem.Controlsパッケージにありますのでこれも指定します。

現在のキーボードはKeyboard.currentで得られ、その後プロパティでa.Key等とすればそのキーのKeyControlが得られ、その後.isPressedとすればそのキーが押されているかどうかのbool値が得られます。

a.Keyの部分を変更すれば他のキーが押されているかどうかも判定出来ます。

キーの指定は列挙型のKeyを使って行う事も出来ます。

またその1フレーム内だけ押されたかどうか判定したい場合は.wasPressedThisFrameを使用します。

これらのキーは物理的なキーボードの配列でのキーと一致していて、QWERTY配列のQキーはAZERTY配列のキーボードの場合はAキーになります。

実際のキーの名前と一致させたい場合はKeyControl.displayNameを使います。

現在のマウスはMouse.currentで取得出来、プロパティのleftButtonで左ボタンを取得出来ます。

現在のゲームパッドはGamepad.currentで取得出来ます。

今回はPS4コントローラーを接続して確認しますが、わたくしのパソコンかPS4コントローラーの接続状態が悪いのかエラーがちょくちょく発生するので取得出来なかった時はその後の処理はしないようにします。

キーボードやマウスの場合も確認した方がいいかもしれません。

gamepad.leftStick.ReadValue()でPS4コントローラーの左スティックの入力値(Vector2)の値が取得出来ます。

gamepad.buttonEast.isPressedでPS4コントローラーの〇ボタンが押されたかどうかを取得出来ます。

gamepad.dpad.up.wasPressedThisFrameでPS4コントローラーのDパッド(十字キー)の上が押されたかどうかをこの1フレームだけ判定します。

ある特定のキーを押したかではなく、どのキーを押したかを判定する時はInputManagerではInput.inputStringで取得出来ましたが、InputSystemの場合はKeyBoard.current.onTextInputイベントのリスナーにメソッドを追加し同じような機能を実現出来ます。

スクリプトを取り付けたゲームオブジェクトがアクティブになったらKeyboard.current.onTextInputのイベントリスナーにOnTextInputメソッドを追加し、非アクティブになる時はイベントリスナーから削除します。

コメント化しているOnEnableはしていないOnEnableと同じ事をしていてよりわかりやすいかなと思って記述しています。

OnTextInputメソッドでは今打った文字を受け取りそれをコンソールに出力しているだけです。

これで直接ゲームパッド、キーボード、マウスの入力を取得する事が出来ました。

アクション設定ファイルを作成して入力を検知する

ここまでで直接ゲームパッド、キーボード、マウスの入力を取得しましたが、InputManagerの時と同じようにHorizontalやFire1等のボタンにゲームパッドのボタンやキーボードのキー、マウスのボタンの割り当てを行うことで入力デバイスが変わっても同じように入力を受け付けるようにすると便利です。

その為に使用するのが、アクション設定ファイルです。

アクション設定ファイルの作り方

アクション設定ファイルはAssetsフォルダ内で右クリックからCreate→Input Actionsを選択すると何も設定されていない空のアクションファイルを作成出来ます。

UnityのInputSystemの空のアクションファイルの作成

その他は何らかのゲームオブジェクトのインスペクタのAdd ComponentからInput→Player Inputコンポーネントを取り付け、Player InputコンポーネントのCreate Actionsボタンを押すと予め設定が施されたアクションファイルが作成されます。

UnityのInputSystemのアクションファイルをPlayer Inputコンポーネントから作成

Player Inputコンポーネントはアクション設定ファイルのデータを使って実際に操作する時に使用するコンポーネントです。

使い方は後で見ていきます。

アクション設定ファイルの設定

試しに空のアクションファイルを作成し、アクションの設定をしてみましょう。

Assetsフォルダ内で右クリックからCreate→Input Actionsを選択し、名前をMyControlとします。

出来たMyControlをダブルクリックするか、インスペクタのEdit assetボタンを押すとアクション設定ファイルウインドウが開きます。

UnityのInputSystemのアクション設定ファイルのEdit assetボタン

空のアクション設定ファイルの場合は以下のようになります。

UnityのInputSystemのアクション設定ファイルウインドウ

Auto Saveにチェックを入れると自動で変更した設定が保存されますが、チェックしない場合は手動でSave Assetボタンを押して保存する必要があります。

Action MapsはActions(InputManagerのHorizontalやFire1に該当)の全体を表す名前でActionsはアクションの名前とキーボードのキーやマウス等の割り当て、Propertiesは選択したアクションのプロパティが表示されます。

Action Mapの作成

アクションマップを作成してみます。

アクション設定ウインドウでAction Mapsの横の+を押し、名前をPlayerとします。

アクションマップを作成すると一つActionが作成されます。

UnityのInputSystemのAction Mapsの作成

Actionの作成

アクションのNew Actionを選択した状態でダブルクリックするかF2キーを押して名前をMoveと変更します。

これでInputManagerのHorizontal等と似たようなMoveというアクションが出来ました。

Moveアクションの設定

Moveアクションに設定をしていきます。

MoveのPropertiesのActionのAction TypeをValue、Control TypeをVector2とします。

これでMoveは値を取得するタイプのアクションでVector2にフィルタリングをします。

UnityのInputSystemのMoveのProperties設定

矢印キーのバインド

Moveアクションに割り当てるキーの設定をしてみます。

最初からあるMove下の<No Binding>はとりあえず削除します。

Moveの下の<No Binding>を選択し、右クリックからDeleteを選択するかShiftキーを押しながらDeleteキーを押して削除します。

Moveの右の+を押してAdd 2D Vector Compositeを選択するか、Moveを選択した状態で右クリックからAdd 2D Vector Compositeを選択します。

UnityのInputSystemのアクションに2D Vector Compositeを追加する

追加すると以下のようにUp、Down、Left、Rightの複合型のバインディングが作成されます。

UnityのInputSystemでアクションに2D Vector Compositeを作成した結果

Upを選択し、PropertiesのPathの右のリストメニューを押します。

UnityのInputSystemの2D VectorのUpの設定

出てきたリストメニューの左上のListenを押した状態で該当するボタンやキーを押すとそのリストに関する項目だけが表示されるので便利です。

ここではListenを押してキーボードの矢印キーの↑を押し、出てきたUp Arrow[Keyboard]をマウスの左ボタンで選択します(キーボードのEnterだとEnter[Keyboard]の項目が出てしまう・・・)。

UnityのInputSystemのMoveアクションの2D VectorのUpのバインディング設定

同じようにDown、Left、Rightも対応する矢印キーをバインド(結びつける)してください。

これでキーボードの矢印キーの設定が出来ました。

2D Vectorという名前だと分かりずらいのでArrowに変更します。

UnityのInputSystemのMoveアクションの2D VectorをArrowに変更

ゲームパッドの左スティックのバインド

次にPS4コントローラーの左スティックのバインドを追加します。

Moveアクションの右の+を押しAdd Bindingを選択します(最初の<No Binding>削除しなくても良かったですね・・・)。

新しく出来た<No Binding>を選択し、PropertiesのPathにLeft Stick[Gamepad]を設定します。

UnityのInputSystemのMoveにゲームパッドの左スティックをバインドする

これでゲームパッドの左スティックもMoveにバインドされました。

Fireの設定

次に新しくFireアクションを作成し、キーボードのSpaceキーを押した時とマウスの左ボタンを押した時の設定をします。

Actionsの右の+を押して新しいアクションを作成し、名前をFireとします。

FireアクションのAction TypeはButtonにします。

UnityのInputSystemのFireのAction Typeの設定

マウスの左ボタンのバインド

<No Binding>を選択し、PropertiesのPathの右を押し検索窓でLeft Buttonと入力し、出てきたLeft Button[Mouse]を選択します。

UnityのInputSystemのFireアクションのマウスの左ボタンの設定

キーボードのSpaceキーのバインド

次にキーボードのSpaceキーのバインドを設定します。

Fireアクションの右の+を押し、Add Bindingを選択します。

新しく出来たバインド設定を選択し、PropertiesのPathの右のリストメニューを選択し、Listenボタンを押した後、キーボードのSpaceキーを押して出てきたSpace[Keyboard]を選択します。

UnityのInputSystemのFireアクションのSpaceキーのバインドの設定

Control Schemeの作成

アクション設定ファイルにコントロールスキームを作成することで、バインドするキーやボタンにスキームを設定し、そのスキームだけを表示するように出来ます。

アクション設定ウインドウの左上のNo Control Schemesを押し、Add Control Schemeを選択します。

UnityのInputSystemのコントロールスキームの作成

試しにキーボードとマウス操作のスキームを作成してみると以下のようになります。

Scheme Nameは任意で、ListにKeyboardとMouseを追加します。

UnityのInputSystemのスキームの設定

同じようにゲームパッドのスキームも作成します。

Scheme NameはGamepadでListにGamepadを追加します。

すると作成したバインドの所でコントロールスキームのチェックを入れることが出来るようになります。

UnityのInputSystemのバインドにコントロールスキームのチェックが表示されるようになった

キーボードとマウス操作のコントロールスキームはKeyboard&Mouseにチェックを入れ、ゲームパッドのコントロールスキームはGamepadにチェックを入れます。

左上のAll Control Schemesを選択した状態だと全てのスキームが表示されますが、例えばGamepadスキームだけを選択するとPropertiesでGamepadにチェックを入れたバインドしか表示されません。

これでアクション設定ファイルの作成が出来ました。

スクリプトで入力を受け取る

アクション設定ファイルが出来たので、次は設定したアクションのキーやボタンが押された時にそれらをスクリプトで取得してみます。

Player Inputコンポーネントを使ったやり方

最初はPlayer Inputに先ほど作成したアクション設定ファイルのMyControlを設定して、該当するボタンが押された時に何らかの処理をするやり方をしてみます。

ヒエラルキーのMainCameraを選択し、インスペクタのAdd ComponentからInput→Player Inputを選択します。

Player InputのActionsにMyControlを設定します。

UnityのPlayerInputコンポーネントの設定

BehaviourをSend Messagesにして取得

BehaviourをSend Messagesにしたやり方をやってみます。

BehaviourをSend Messagesにすると該当するアクションボタンが押された時にOn+アクション名のメソッドが呼ばれます。

なのでMoveの場合はOnMoveメソッド、Fireの場合はOnFireメソッドが呼ばれます。

試しに新しくSendMessageScriptスクリプトを作成しMainCameraに取り付けて実験してみます。

OnMoveはMoveアクションにバインドしたキー等を押した時に呼ばれ、引数でInputValueを受け取ります。

受け取ったinputValueのGetメソッドでジェネリックでVector2を指定しVector2の値をコンソールに出力しています。

PS4コントローラーを使う場合はジャイロ機能のノイズで入力値が発生する可能性があるので、UnityメニューのEdit→Project SettingsのInput System PackageのFilter Noise on currentにチェックを入れておきます。

UnityのInputSystemPackageのFilter Noise on currentにチェックを入れる

PS4コントローラーの左スティックやキーボードの矢印キー、マウスの左ボタン等を押して確認してみてください。

PS4コントローラーの接続先のUSBポートによっては左スティックがうまく反応しないかもしれません。

フィールドにVector3型のvelocity等を用意しておいて、OnMoveメソッド内でその値をvelocityに足すとキャラクター移動の処理も出来そうですね。

BehaviourをInvoke Unity Eventsにして取得

次にPlayer InputのBehaviourをInvoke Unity Eventsにしたやり方をやります。

新しくUnityEventScriptスクリプトを作成し、MainCameraに取り付けます。

MainCameraに取り付けてあったSendMessageScriptは削除しておきます。

こちらは引数でInputAction.CallbackContext型の引数を受け取るようにOnFireとOnMoveメソッドを定義しています。

Player InputのEventsのPlayerのMoveとFireにUnityEventScriptのOnMoveとOnFireを実行するように設定します。

UnityのInputySystemのPlayerInputでBehaviourがInvoke Unity Eventの時の設定

これでMoveアクションとFireアクションにバインドしたキーやボタン等が押された時にUnityEventScriptのOnMoveとOnFireメソッドをトリガーするようになりました。

スクリプトでアクション設定ファイルのインスタンスを生成するやり方

Player InputコンポーネントにMyControlアクション設定ファイルを設定してそれを取得しなくてもスクリプト内でアクション設定ファイルのインスタンスを生成してそれを利用するやり方もあります。

まずはAssetsフォルダのMyControlアクション設定ファイルを選択し、インスペクタのGenerate C# Classにチェックを入れてApplyボタンを押します。

UnityのInputSystemのアクション設定ファイルのラッパークラスを作成する

そうするとMyControlのC#のラッパークラスが作成されます。

特にクラス名等をいじっていなければMyControlスクリプトが作成されます。

MainCameraのPlayer InputコンポーネントとUnityEventScriptを削除し、新しくCreateInputActionControlスクリプトを作成し取り付けます。

MyControl型のmyControlフィールドを宣言します。

AwakeメソッドでMyControlのインスタンスを生成し、PlayerアクションマップのMoveとFireアクションのperformedのフェーズ(段階)でそれぞれOnMoveメソッドとOnFireメソッドをトリガーするように設定します。

performedフェーズはアクションとの相互作用が完了した時のフェーズで他にはstarted(アクションとの相互作用を開始した時)等があります。

スクリプトのフィールドにInputAction型のフィールドを用意しインスペクタで設定するやり方

スクリプトのフィールドにInputAction型のフィールドを用意し、インスペクタでアクション設定し、スクリプトから取得をすることも出来ます。

MainCameraのCreateInputActionControlを削除し、新しくCreateInputActionScriptを作成しMainCameraに取り付けます。

CreateInputActionScriptのインスペクタでアクション設定をします。

UnityのInputSystemのアクション設定ファイルを作らずインスペクタで設定する方法

この場合はあらかじめアクション設定ファイルを作らずインスペクタで同じように設定していきます。

スクリプトでアクションのバインドも設定するやり方

スクリプト内でInputActionの作成とバインドの設定をする事も出来ます。

行っていることはアクション設定ファイルを作った時と同じ設定をスクリプトで記述しているだけです。

キーボードの矢印キーはコンポジットで作成したので作成したMoveアクションのInputActionにAddCompositeBindingメソッドを使って追加しています。

バインドの設定文字列はアクション設定ファイルのActionのPropertiesのPathの右のTを押した時に出てくる文字列と同じ物を指定します。

例えばArrowのUpであれば以下のようにTキーを押すと該当する文字列に変わります。

UnityのInputSystemのバインドの表示を変える

通常のバインドはAddBindingメソッドで行えます。

ゲーム中にスクリプトからバインド設定を変更する

ゲーム中に設定したアクションの割り当てを変更する事も出来ます。

BindInputActionにUpdateメソッドを追加します。

マウスの右ボタンを押したらFireアクションにバインドしていたキーボードのSpaceキーをキーボードのTabキーに変更しています。

UI操作をInputSystemで対応する

UIの操作はEventSystemのStandalone Input Moduleコンポーネントで設定されていましたが、Standalone Inpput ModuleではInputManagerのボタン等が設定されています。

InputSystem用に切り替えなければいけないので、ヒエラルキー上のEventSystemを選択し、インスペクタのReplace with InputSystemUIInputModuleボタンを押します。

UnityのEventSystemをInputSystemUIInputModuleに変更する

以下のようにStandalone Input ModuleコンポーネントがInputSystemUIInputModuleコンポーネントに変わります。

UnityのEventSystemのStandaloneInputModuleをInputSystemUIInputModuleに変更する

Actions AssetにはPackage/Input System/InputSystem/Plugins/PlayerInput/DefaultInputActionsアクション設定ファイルがデフォルトで設定されます。

Actions Assetには自分で作ったアクション設定ファイルも設定出来ます。

空のゲームオブジェクトを選択し、インスペクタのAdd ComponentからScripts→UnityEngine.InputSystem.UI→Input System UI Input Moduleを選択して取り付ける事も出来ます。

終わりに

InputManagerの使い方に慣れているので、InputSystemへと変更するのはなんだか難しいですね。(^_^;)

InputSystemのドキュメントに情報がたくさんありますので、他にやりたい事があれば参照してみてください。

情報量が多すぎて大変ですが・・・(´Д`)

InputManagerが完全に廃止されたら使用している全ての記事の内容を変更せにゃいかんのか・・・・こりゃ大変だ。

InputSystemを使ったキャラクター操作やPlayerInputManagerコンポーネントの使い方については以下の記事を参照してください。

UnityのInputSystemを使ったキャラクターの操作機能
Unityの新しい入力システムであるInputSystemを使ったキャラクターの操作機能とローカルマルチプレイヤーゲーム対応を作成してみます。

参考サイト

以下のInputSystemのドキュメントから詳細が見れます。

InputSystemのドキュメント

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