【Unity2D】コードが肥大化してきたらスクリプトを分割しよう
こんにちは。なおキーヌです。
ブログ毎日更新は332日目になります。
グリッド移動を実装しようと思ったのですが、思いの他スクリプトのコードが肥大化してきて見通しが悪くなってきたため
そろそろ処理別にファイルを分けていこうかなと思います。
この辺はちょっと設計を考えないと後々大変なことになりそうな予感がしますね。
現状Controllerというスクリプトをプレイヤーオブジェクトに取り付けて全て処理しています。
なぜコントローラーかと言うと、プログラミングではMVCという考え方があってそれに準じて作ろうかなと思ってたのですが
結局全てControllerスクリプトに記述しちゃってるので意味なくなってます(笑)
なのでそろそろ名前に適した処理だけを書く方向性にします。
今のところ内容は移動処理とキー処理ぐらいなので、移動処理は別スクリプトに分けたいですね。
Controllerは本当にプレイヤーが入力したコントロール処理をするためのものにします。
キー入力を受け付け、それを元にステートを変更するといった形です。
ステートというのはどのスクリプトからでも参照だけは出来るようにしておいて情報を取れるようにしておきます。
いわゆるリードオンリー(ReadOnly)的な仕組みです。
ステートを変更できるのはステートスクリプトのみ。
コントローラーや移動のスクリプトはそれぞれ担当の処理をしつつ変更をステートに通知するだけ
といった感じにしておけばメンテナンス性もかなり上がると思います。
こうやっておくと、どこでバグが発生したかもわかりやすいのでいいことづくめです。
ただ、子スクリプト孫スクリプトと親を継承しまくってしまうと今度はコールバック地獄が起こるので
出来る限りネストを深めないシンプルなつくり方を心がけましょう。
バックアップを取ってから作業開始
できればGITとかで管理してもいいのですが、まだそこまでのものでもないのでスクリプトファイルをコピーしておけばOKです。
とりあえずControllerスクリプトから移動処理や掴み処理等、インプット処理以外のものを抜き出してみましょう。
Controller.csを修正
現状以下のキー入力関連処理を実装しています。
- 上下左右、GとSの入力受付
- キー入力状態の保持する配列と出し入れするための関数
- 配列にキーが含まれているかどうかを調べる関数(Linq)
Controllerにはこれぐらいあればいいと思います。
後はあとはキー入力配列を管理スクリプト側で参照できると色々便利そうです。
Move.csの作成
条件に応じてオブジェクトが移動するためのスクリプト。
ホントにそれだけ。
管理スクリプトで1番動け!という命令を出したら止まれという命令を出すまで
このスクリプトが作動し続けるといった感じ。
ただ、これが正解なのかどうかはわかりません。
本来ならキャラクタークラスとか作ってそれを継承して親が持っているmove関数を使ってーとかやるのですが、
Unityの場合コンポーネント単位なのでこういった処理別のスクリプトを作って汎用性を持たせてやればメンテナンスも楽になりそうなんですよね。
ただ、これをやることによって管理スクリプト側での処理が大変になるような気がします。
とりあえず体験版までなのでそこまで肥大化はしないと思うのですが、
作ってみてダメそうなら別の方法を考えて実装します。
PlayerAction.csの作成
基本的にユーザーが出来るアクションをまとめたスクリプトです。
これも基本的には管理側で命令が出されたら動き続けるといった仕組みにします。
基本的にプレイヤーにしかアタッチしないコンポーネントなので結構好きに組めそうですね。
行動別にスクリプト化してもいいけどそうするとコンポーネント数が増えすぎて重くなりそうな気がするので
アクション関連の処理は一つにまとめようと思います。
モンスターにしてもそうですね。
ベースを作ってそれを派生させて動きのバリエーションを作っていくといった感じでしょうか。
このやり方でいいのかが疑問になるがとりあえず突き進もう
一人で開発してると「このやり方、正しいのだろうか……」って思うことありませんか?
私はしょっちゅうあります。
そして正解を探そうとググるのですが、色んなやり方が出てきてどれが正しいのかわからなくなります。
冷静になって考えてみると別に正解は一つじゃないのがクリエイトなんですよ。
そもそも正解なんてない。
選択したのが正解なわけです。
なのでうだうだ考える前にとりあえず作ってみましょう。
そしてそこでぶつかった問題(処理的に重いとか管理が大変とか)が出てきた時に考えましょう。
とりあえず作るんです!作れ作れ!
次回はそれぞれの処理を切り分けて管理しなおしてみようと思います。
目標はスクリプトを分けても今動いている状態と同じ状態に持っていくことです。
それでは。