夏が終わらない
もはや首掛けの扇風機が体の一部となっている皆さんこんにちは。この夏はどこに行くにも欠かせない存在で、暦の上で夏が終わっても気温がちっとも下がらない為、未だに首に掛けて過ごしているのですが、街ですれ違う人の視線がチラチラ扇風機の方へ向けられている気がして恥ずかしくなってきました。でも外せない、だって暑いし。
「W.T.」アップデート(予定)
一人称視点の3D脱出ゲーム「W.T.」ですが、早期アクセス版に対するゲームパッド対応が一通り完成しました。
現在は動作確認中ですがWindows版とMac版の二つで確認する必要があるため、Steamへアップデート版をリリースするのはもう少し先になりそうです。
当初は8月末辺りにリリースしたかったのですが、Mac版での検証が一昔前のMacBookAirで行うため性能対策も必要で、そしてその対応をWindows版にも反映する作業がいる為、思ったよりも時間が掛かりそう。
まぁ、進捗が遅れている一番の要因はAC6だったり、AC6だったりするのですが、これはやたら難しいくせにリトライのロード時間が短いフロムが悪い、ゲームオーバーになっても直ぐに再開するのでずっと遊んでしまう。バルテウスで二日、シースパイダーで半日潰れてしまいました。
InputSystemを使おう
InputSystemはPackage Managerからインストールして使う事ができます。
InputSystemを導入するとキーボードやマウス、ゲームパッド、ジョイスティック、タッチディスプレイなど様々な種類のデバイスを統合して扱うことが可能なため、InputManagerを使うよりもコーディングの量が少なく、ゲームパッドやOSの違いでアレコレ悩む必要が無くなります。
例えばゲームパッドの方向キーの入力を判定したい場合、XInput形式、DualShock形式に関わらず現在接続されているゲームパッドはGamepad.currentで参照でき、方向キーの入力はGamepad.current.leftStick.ReadValue()で取得(Vector2で各方向-1~1)されるので、Input.GetAxisを使って各形式でマッピングされたAxisの名前を指定するよりは随分簡単になります。
この辺の基本的な内容はUnityの公式で発信されているので、下のリンクを参照してください。
InputActionを使おう
InputSystemを使えばゲームパッドは形式やOSを考慮することなく入力値を参照できることは分かりましたが、マウス+キーボードとゲームパッドで入力を統合したい場合はどうしたら良いでしょうか?
InputSystemでは、マウスやキーボード、ゲームパッドなど複数の入力デバイスを統一して扱えるようにするコンポーネントInputActionが用意されています。
例えば下の図のようなCubeに対して、Wキーを押しても、上方向キーを押しても、ゲームパッドの左スティック上を押しても、前(Z方向)に移動させたい場合、
InputActionに「Wキー押下、上方向キー押下、左スティック上押下」の入力イベント(Binding)を登録して、InputAction経由で入力値を取得すれば、登録した入力イベント全てで「前(Z方向)に前進」を行うことができます。
まず、Cubeを操作するスクリプトにInputActionの定義を追加し、インスペクターで入力イベント(Binding)の登録を行います。
手順はインスペクター上に表示されているInputActionの項目に対して
- 「+」ボタンを押下
- Add Binding項目を選択
- Pathドロップダウンから追加したい入力イベントを選択
の順で設定します。今回は「Wキー」「上方向キー」「左スティック上」を登録しました。
スクリプトにてInputAction(ActionCtl)から入力値をReadValueで取得し、CubeをZ方向へ移動させます。
「Wキー」「上方向キー」「左スティック上」の全ての入力でCubeを前進させることができました。
前後に動かしたい
上記の設定は入力イベント(Binding)の登録であるため、ReadValueから取得できる値は0~1の値となりますが、これを-1~1として「前方向と後方向」で判定したい場合は[Binding]を登録するのではなく、[Positive/Negative Binding]の登録を行います。
[Positive/Negative Binding]では0~1の値を取るPositiveイベントと-1~0の値を取るNegativeイベントを登録することになります。
上記の設定を[Positive/Negative Binding]に変更
この設定で各キーに応じて0~1、-1~0の値が取得できるので、スクリプトを変更することなくCubeを前後方向に動かす事ができます。
自由に動かしたい
[Positive/Negative Binding]で「正方向・負方向」それぞれでイベントを設定することができるので、これを利用すれば「前後方向」「左右方向」の入力値が取得できるようになります。とはいえ、「前後方向」「左右方向」でInputActionを用意するのはちょっと面倒です。
ゲームを制作する上ではキャラクターの移動の為の「前後」「左右」以外にも視点移動の為の「前後」「左右」の指定もあるため、それらを含めると用意するInputActionが増えていき煩雑になります。
この為、InputSystemには、InputAction AssetのActionをラップして管理するPlayerInputコンポーネントが用意してあります。
PlayerInputコンポーネントをアタッチしてインスペクターからCreate Actionsボタンを押下します。
すると色々なBindingが登録されたInputActionアセットがプロジェクト内に作成されます。
こちらのInputActionアセットをクリックして開いてみると分かりますが、ゲームに必要な操作に対する入力イベント(Binding)が一通り登録されており、一般的な操作方法を考えているのなら、そこから変更する必要はありません。
PlayerInputコンポーネントをアタッチすると、各デバイスの入力は一旦PlayerInput側で受け取り、必要に応じてSendMessageか登録したコールバック関数への通知が行われます。
今回はInvoke Unity Eventsを設定してコールバック関数(OnPerformed)への通知を受け取るように設定しました。
スクリプトにてキー、ステック(Axis)の入力応じてReadValue<Vector2>で値を取得、その値に応じてCubeを動かします。
これを実行すると
いろんな入力で前後左右にCubeを移動させることができました。
まとめ
InputSystemを導入してInputActionを使うと様々な種類のデバイスを統合して扱うことが可能となることが分かったと思います。
ゲームを制作する上ではPlayerInputコンポーネントを導入すれば、デフォルトのままでもゲーム内の一通りの動作をデバイスの種類よらず、同じロジックで実装することが可能となります。
これからはInputSystemの導入が必須になるかもしれませんね。