おもちゃバコ

中身スカスカ♡

Unity: InputSystemでローカルマルチに対応する(改)

こんにちハンドラ
最近座り方がヤバくて腰が終わってきました.

今回は前に書いたInputSystemでローカルマルチを実現するやつの改良です.
lambda00.hatenablog.com

前回の記事は,「プレイヤ(操作されるもの)に直接イベントを埋め込む」実装を行っていました.
小さな規模のゲームだと大丈夫かもしれませんが,大きな規模のゲームになるとプレイヤが神クラスになる可能性が高いです.

そこで,今回は,Singletonパターンを使用してコントローラを管理するControllerManagerを作成し,コントローラを使用する側でControllerManagerを参照するようにしました.


参考文献

Singletonについて
hikatech.com
nabesi777.hatenablog.com
blog.negativemind.com
qiita.com


Singletonパターン

すごく簡単かつ雑に説明すると
インスタンスが1つしか存在しないことが保証されるクラス設計のこと
です.
実装については,参考文献ママさんなのでそちらを参照してください.


イメージ

SingletonのControllerManagerにアクセスして入力情報をもらってくる感じです.

ControllerManager

本題です.
ControllerManager.csの役割としては,下記の通りです.
・追加されたコントローラ(入力装置)の管理
・指定されたコントローラ番号(ID)に応じた入力を返す
Singletonにした理由は,シーンをまたいでも入力を受け取りたいからです.

まず,Singletonパターンを継承したControllerManager.csを作成し,ControllerManagerオブジェクトにアタッチします.
今回はコントローラのスタートボタン,キーボードのエンターを入力時にControllerオブジェクトが生成されるようにInputSystemを設定しています.

ControllerManager.csでは,入力装置が追加(スタートボタンまたはエンターキーが入力)されたときにアタッチされている「Player Input Manager」に設定されている「Controller」プレハブを生成します.
このとき,OnPlayerJoinedイベントが実行され,子要素としてControllerプレハブが追加されます.

ControllerBehaviour

次に,コントローラの振る舞いについてです.
基本は,前回の記事でプレイヤに直接埋め込んでいた処理をただ移行しただけです.

機能としては,
・ボタン状態の判定: PRESS, HOLD, RELEASE, NONE
十字キーの値を取得
ぐらいです.

ボタン状態の更新をUpdate()で行っているのは,イベントハンドラが呼ばれるタイミングが早すぎてPRESSとRELEASEの判定がきちんとできないからで,特に深い理由はありません.


PlayerController

使用方法についてです.
初めにコントローラIDを指定して,接続されるまでコルーチンで待っています.
接続後,プレイヤの入力が反映されます.


実行

シーン遷移をしたらプレイヤは消滅しますが,ControllerManagerは生きていることが確認できます.
また,Singletonで設計したクラスはDontDestroyOnLoad()しても,1つなのが確認できますね.
(XYZはSingletonを使用せずに,ただDontDestroyOnLoad()したやつです.)


まとめ

これでプレイヤが神クラスになることを回避できた(?)のかな.