Unity設計
Unity触っていて不味い感じになる気しかしなかったので、設計論を調べる
全部Monobehaviorに依存していてテスト困難だったりするのも理由の一つ
MVP
Unityだとなぜか設計というとこの話ばかり出てくる
Model
View
Presenter
Presenterを通すことでView(UI,3Dモデル)とModelの直接の依存を防ぐ
PresenterのみModel, Viewへの参照をもつ
code:mmd
graph LR
UserInput --> View
View-->Presenter-->Model
Model-->Presenter-->View
ViewはユーザーからのInput, またユーザーへのoutputの責任を持つ
Viewはユーザーと対話するためのもの、つまり広い意味でのIO部分
IniputとOutputを渡すだけで、Outputの生成はModelで行う
UnityではViewがMonobehaviorになりがち
UIとかキャラクター表示とかアニメーションとか
Modelは実際のデータや、そのデータの処理などのいわゆるドメインロジックも含めている
PresendterはViewからinputを受け取り、モデルを使ってデータを生成して、その結果outputをViewに渡す
PresenterはViewからの通知(User input)をどうにか検知する必要がある
データバインディングやpub/subの仕組みでView -> Presenter方向の通知を行う
unityではここをUniRXでやっていたという例が多いが、ぶっちゃけなんでもいい。
ViewのイベントでPrenseterの関数をコールバックするでもよい。
Presenterが結局Fat Controllerになってしまうような?
Web界隈でよく聞くMVCと似たような設計技法
MVCの派生の一つらしい
MVCだとControllerでinput処理してModelとViewを変更するのでMVCとは違う
これは正確にはRailsのModel2MVCらしいが
Fat Contrrollerになりがち
原初のMVCだとModelがViewに変更を通知してView側を変更していたっぽい
Fat Contollerにはなりにくいが、ModelとViewの結合度が上がってしまっている
結論としてはModel2MVCとMVPは目指しているところはかなり似ている。
というかほぼ一緒
Inputを取り扱うのがControllerかVIewくらいにしか思えない。
Model
値の計算、ゲームロジック
VIew
UI、Animator等
Presenter
Modelの変化をViewに反映
ViewからのinputをModelに反映
UnityではSerialized Filedを使うことでDIをEditor側で実現しているといえる。
コンポーネントが増えると依存関係をエディタで解決しているといえる
数が増えるとしんどいのでコードとして解決できるといいよねということでDIコンテナの仕組みがある
https://www.youtube.com/watch?v=NWhGShdYq6A&ab_channel=Gotanda.unity
Interfaceだとかクラスとか具体的な手法は些末な話で責務やフローの整理というのが設計で超重要というのはそのとおり
結局様々な設計手法で話しているのも本質的には全部コレ
大まかにはどの程度のまとまりで各コンポーネントの責務をまとめるか、データフローを作るかという話でしかない
それを実現するのに細かい流派があるという程度の話でしかない。
これはカオスで定性的なパターンが作りにくいゲーム設計でも同じなんだという話
マルチシーン設計
シーンとはゲームオブジェクトのグルーピング単位といえる
以下のようにシーンを区切って、シーンを合成してゲームを構成させることもできる
基本システム、プレイヤーなどのシーンA
ステージマップ1のシーンB
ステージマップ2のシーンC
UIシーンD
Aのシーンは常駐させて、シーンBとシーンCを切り替える
ボタンが押されるとメニュー等のUIシーンDがenable
この手法をマルチシーンと呼ぶ。
機能ごとにシーンの分割も可能。
各機能ごとに触るシーンが変わるとコンフリクトのリスクが低減
LoadSceneMode.Additiveというモードでシーンをロードすると同時に複数のシーンを読み込める
チュートリアルでよくある場面ごとに完全に独立させてシーンで作るやり方は
プレイヤー、システムなどの共通のゲームオブジェクトを毎シーンで作らないといけない。
マルチシーンだと共通の処理などは特定のシーンに集中すれば他のシーンでは実装不要になる。
ただしsingle sceamもメリットは大きくシーン遷移でゲームオブジェクトの解放が行われる
unityは基本としてシーン遷移すると遷移元シーンのオブジェクトは自動解放される
unityの基本思想はロードするシーンは同時に一つだけ
マルチシーンだと常駐シーンが発生するのとシーン切りかえでオブジェクトの自動解放されない
シーンきりかえごに自前でのメモリ解放を行うことになる。
簡単にメモリリークを引き起こせる。
メモリ管理を自前でコントロールする必要になる。
またシーンまたぎの参照がサポートされてない機能もある点に注意。
シーンまたぎで情報をやり取りする上で何かしらの工夫が必要になることも多い。
参照され続けるゲームオブジェクトは解放されない。
メモリ解放条件が参照カウント方式
よくあるのがシーンまたぎで参照されていて、参照元が参照をNullで潰さないケースで発生
この問題もマルチシーンをすることによる潜在的な問題とも言える。