ぐっちーの駄弁り部屋

個人的に制作しているものの進捗や日常について不定期投稿

知らない間にUnityの入力周りが変わっていた件について

皆さんお久しぶりです。ぐっちーです

ここ最近個人開発だったり、ブログネタだったりを集めることがなかったのでブログの更新が滞ってましたが新生活も落ち着いてきたので個人開発を再開しようかなと思った次第です。

なので何か進捗があればTwiterか記事にできるようなものならこちらに上げようかなと思います。

さて本題ですが仕事でUnity使ってるわけではないのでかなり長い期間Unityを触っていなかったんですが久々にUnityでゲーム開発しようと思って色々調べていたら気になる記載が…

Unityの新入力システム・InputSystemを使おう

forpro.unity3d.jp

え、Unity入力関係変わってたの?

一応以前のInput.GetButtonDownみたいなのも使えるみたいですが使い方を調べていたら圧倒的にInputSystemのほうが使いやすそうでしたので今回は備忘録的な感じで導入と簡単な使い方を残しておきたいと思います。

InputSystemとは

InputSystemは各種入力デバイスからの入力を汎用的・統合的に取り扱うように導入されたシステムで2020年4月にversion1.0.0がリリースされたみたいです(リリース今年じゃなかったのか)

Unity対応プラットフォーム全てに対応しているようで今後こちらが標準になっていくみたいです

InputManagerとの違い

これまではInputManagerというもので入力を扱ってきたかと思います。Input.GetAxisで上下左右を取ったり、Input.GetButtonDownでボタン入力を取得したりですね。 また、Preferenceから"Horizontal"や”Fire”などの名前でボタンを割り当てて使う場合もあったかと思います。昔からUntyを使っている人たちは非常に馴染み深いと思います。

InputSystemがこれと何が違うかというとまず、スマホゲーなどを開発した際の仮想的なスティックやボタンにも対応している点です。

これまでは自分でタッチ判定などを作成して対応する必要がありましたがInputSystemにはそれらの仮想的なボタンをコントローラのボタンと同じように扱う機能が備わっているので非常に扱いやすくなっています。PCとスマホ両方でリリースするゲームとなったときに非常に助かる機能だと思います。

また、InputManagerにキーを登録する際には各コントローラの割当番号的なもので登録していました。こちらの番号はコントローラによって異なるので逐一確認しなければなりませんでした。これが非常にめんどくさかったわけですがInputSystemではその必要がないみたいです。

対応しているコントローラーは * XboxコントローラーなどXInput方式のもの * DualShock(PS4のやつ) * Joy-Con(ビルドプラットフォームがSwitchの場合)

です。PS5のDualSenseはまだ対応していないようですが拡張プラグインを作成している方がいて、Github上で公開されていましたのでひとまずはそちらを使うのがいいかと思います。

github.com

ちなみにスマホの加速度センサーやジャイロにも対応しているみたいです

導入編

インストール

ではでは導入していきましょう。めんどくさいことはないのでサクサク行きます。

いつ頃からか忘れましたがUnityではこういったパッケージやアセット関連の導入をPackageManagerに統一したみたいですね。非常にいいことだと思います。UnityEditorからAssetStoreに接続するの結構時間かかってたイメージなので助かります。

InputSystemも例にもれずPackageManagerから導入します。PackageManagerはアルファベット順になっているのでそれで探すか検索窓に”InputSystem”と入れて出てきたらInstallを選択します。

インストールするとネイティブバックエンドを有効にするか聞かれますのでYesと答えます。するとUnityが再起動しますがその後からはInputManagerによる入力は使えなくなるので注意してください。(InvalidOperationExeption吐くみたい)

一応ProjectSetting>Player>OtherSetting>ActiveInputHandleから使いたい方を選択できるようになっているので両方使いたいよって方はそちらからどうぞ

これでInputSystemを使用することができるようになりました。そうです。実際のところこれだけです。 以下のようなコードを記述すれば実際に入力をとってこれます。

using UnityEngine;
using UnityEngine.InputSystem;

public class AppInputExample : MonoBehavior{
 private float speed = 5.0f;
 void Update(){
  if(Gamepad.current == null) return;

  if(Gamepad.current.buttonNorth.wasPresseddThisFrame) Debug.Log("☓(A)ボタンが押されました");

  Debug.Log(Gamepad.current.leftStick.ReadValue()); //vector2
 }
}

コントローラ右側のボタン群を東西南北で表現してるのは面白いと思いますww

基本的にはInputDevice.currentの形で接続されているデバイスからの入力が取れるのでKeyboard.currentでキーボードの入力が、Mouse.currentでマウスの入力が取れます。

もう少し設定する

上記のように値を取得してもいいでのすがゲームを作るなら「このボタンで攻撃」「このキーでジャンプ」みたいなものが作りたいかと思います。そういった設定をする機能ももちろんあります。

Actionという概念でそのような動作をキーやボタンにバインドすることができます

Actionを使用するにはまず何かしらのオブジェクトにPlayerInputコンポーネントをアタッチします

アタッチしたらCreateActionsボタンからInputActionAssetを作成してActionsにアタッチします

このInputActionAssetというのが操作とキーやボタンを結びつける役割を担っています
InputActionAssetを開くと以下のようなウインドウが表示され最初からいくつかの設定がされているのがわかります。

例えばこの画像で行くとMoveというActionにパッドのLスティック、キーボードのWASD、XRコントローラやJoystickの入力などが割り当てられています。これはどれかの入力の値をMoveというActionから取得できるよという意味でMoveにさえアクセスすれば入力方式によってプログラム側で分けて記述する必要なく移動方向が取得できるということです。

それでは次の項でActionの使い方に触れていきます

使い方編

Actionにバインドを追加する

では任意の操作を追加していきましょう。今回はジャンプボタンを追加します バインドの追加はActions右側の+をクリックして行います。名前をJumpにしてその下のを選択します

そうしたらPathを選択し設定したいキーを割り当てます。今回はパッドの☓ボタン(Aボタン)を割り当てます。

キーマウでも動かしたいならJumpの右側にある+を選択してバインドを追加し、同様の手順でキーを追加しましょう

スクショミスってますがUse in control schemeを適切に設定してください。

このような感じで操作と入力を結びつけて扱いやすくなりましたので今度はスクリプトからこれらを読んでいきます。

スクリプトからActionを処理する

実はActionの値をスクリプトで受け取る方法はいくつかあります。メッセージを送信するものやUnityEvent、C#のEventを発火させるものなど様々ですがこの記事では個人的に一番使いやすいと感じたものをご紹介します。

InputActionAssetを選択するとInspectorに次のような表示がされると思います

ここでGenerate C# Classを選択すると先程のActionたちをC#のクラスにしてくれます すると先程のActionがプロパティになってくれるので非常に直感的に値の処理ができます。

using UnityEngine;

public class PlayerController : Monobehavior{
 AppInputAction _Input;
 float _Speed = 1f;
 void Awake(){
  _Input = new AppInputAction();
  _Input.Enable();
  _Input.Player.Fire.performed += OnFire;
  _Input.Player.Jump.performed += OnJump;
 }
 
 void Update(){
  var dir = _Input.Player.Move.ReadValue<Vector2>();
  transform.Translate(dir * _Speed * Time*deltaTime);
 }

 void OnFire(InputAction.CallbackContext){
  //攻撃処理的な
 }

 void OnJump(InputAction.CallbackContext){
  //ジャンプ
 }
}

個人的にこの方法が一番使いやすいってだけなので他の方法が良いかもって人はそっちで大丈夫です

その他詳しい使い方

その他の詳しい使い方は冒頭でも紹介した記事で紹介されていますのでそちらで確認してみてください

forpro.unity3d.jp

まとめ

簡単にまとめます

  • いつの間にかInput関連が新しくなってた
  • 従来と違いかなり汎用的なシステムになった
  • 専用のアセットでアクションと入力を結びつけて扱うとより実践的
  • クラス化することで更に使いやすく

こんなところでしょうか。入力周りって個人的に面倒なイメージだったんですがかなり改善されそうな予感

では今回はこのへんで!次はいつになることやら...