![Hero background image](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fa0b4f20b4ea9e3bed4eb7c9a8888ce1673e97230-7000x4000.jpg&w=3840&q=100)
Unityプロジェクトに一般的なゲームプログラミングデザインパターンを実装することで、クリーンで整理された読みやすいコードベースを効率的に構築・維持することができます。デザインパターンは、リファクタリングとテストの時間を短縮し、開発プロセスをスピードアップし、ゲーム、チーム、ビジネスを成長させるための強固な基盤に貢献します。
デザイン・パターンは、コードにコピー&ペーストできる完成されたソリューションとしてではなく、より大規模でスケーラブルなアプリケーションを構築するのに役立つ追加ツールとして考えてほしい。
このページでは、Model View Controller (MVC) と Model View Presenter (MVP) のデザイン・パターンについて説明します。
ここでの内容は無料電子書籍に基づいています、 ゲーム・プログラミング・パターンでコードをレベルアップしよう.
Unityゲームプログラミングデザインパターンシリーズの他の記事は、Unityベストプラクティスハブまたは以下のリンクからチェックしてください:
Model View Controller (MVC)と Model View Presenter (MVP)デザインパターンを使って、アプリケーションのデータとロジックを表示方法から分離することができます。これらのパターンは「懸念事項の分離」の原則を適用し、コードベースの柔軟性と保守性を向上させることができる。
Unityのゲーム開発では、これらのパターンを使って、ゲームのロジックをデータ(Model)、ビジュアル表現(View)、2つの間のインタラクションを制御するロジック(ControllerまたはPresenter)のような個別のコンポーネントに分けることができます。
![MVC](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F22b61826d9230c96e86dd1646693c688780277b3-800x733.jpg&w=3840&q=75)
MVCは、ソフトウェア・アプリケーションでユーザー・インターフェースを開発するときによく使われるデザイン・パターンのファミリーである。
MVCの一般的な考え方は、ソフトウェアの論理的な部分をデータとプレゼンテーションから分離することである。これは、不必要な依存関係を減らし、スパゲッティコードを削減するのに役立つ。
その名の通り、MVCパターンはアプリケーションを3つの層に分割する:
モデルはデータを保存する: モデルは、厳密には値を保持するデータコンテナです。ゲームプレイのロジックを実行したり、計算を実行したりはしない。
ビューはインターフェイスである: ビューは、データをフォーマットし、画面上にグラフィカルに表示します。
コントローラーはロジックを処理する: これを脳と考えてほしい。ゲームデータを処理し、実行時に値がどのように変化するかを計算する。
この懸念事項の分離はまた、これら3つの部分が互いにどのように影響し合うかを具体的に定義している。モデルはアプリケーションのデータを管理し、ビューはそのデータをユーザーに表示します。コントローラーは入力を処理し、ゲームデータに対してあらゆる決定や計算を行う。そして、その結果をモデルに送り返す。
コントローラー自体にはゲームデータは入っていません。ビューもそうだ。MVCデザインは、各レイヤーが行うことを制限している。ある部分はデータを保持し、別の部分はデータを処理し、最後の部分はそのデータをユーザーに表示する。
表面的には、これは単一責任原則の延長と考えることができる。MVCアーキテクチャの重要な利点は、各パートが1つのことをうまくこなすことである。
MVCでUnityプロジェクトを開発する場合、既存のUIフレームワーク(UI ToolkitまたはUnity UI)は当然Viewとして機能します。このエンジンは完全なユーザーインターフェースの実装を提供するので、個々のUIコンポーネントをゼロから開発する必要はない。
しかし、伝統的なMVCパターンに従うと、実行時にモデルのデータの変更をリッスンするためのビュー固有のコードが必要になります。
これは有効なアプローチですが、多くのUnity開発者はMVCのバリエーションとして、Controllerが仲介役となる方法を選択します。ここでは、ビューはモデルを直接観察しない。その代わり、上の図のようなことをする。
このMVCのバリエーションは、モデル・ビュー・プレゼンター設計、またはMVPと呼ばれる。MVPは、3つの異なるアプリケーション・レイヤーによる懸念事項の分離を維持している。ただし、各パートの責任は若干変わる。
MVPでは、プレゼンター(MVCではコントローラーと呼ばれる)が他のレイヤーの仲立ちをする。モデルからデータを取得し、ビューに表示するためにフォーマットします。MVPは入力を処理するレイヤーを切り替える。コントローラではなく、ビューがユーザーの入力を処理します。
イベントとオブザーバー・パターンがこのデザインにどのように組み込まれているかに注目してほしい。ユーザーはUnity UIのButton、Toggle、Sliderコンポーネントを操作できます。Viewレイヤーはこの入力をUIイベントを通じてPresenterに送り返し、Presenterはモデルを操作する。モデルからの状態変化イベントは、データが更新されたことを Presenter に伝えます。Presenter は変更されたデータを View に渡し、View は UI をリフレッシュします。
![MVPサンプルプロジェクト](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fb39b0024e7c75ed12bb66cc24b8c4aa98ba2e82b-800x450.jpg&w=3840&q=75)
MVPのバリエーションを実装する方法の例を含め、さまざまなプログラミング・デザイン・パターンを示すサンプル・プロジェクトがGithubで公開されている。
MVPの例は、キャラクターやアイテムの健康状態を表示するシンプルなシステムで構成されている。この例では、データとUIをミックスした1つのクラスにすべてをまとめているが、実際の制作ではうまくスケールしないだろう。より多くの機能を追加すると、それを拡張する必要があるため、より複雑になる。加えて、テストとリファクタリングは多くのオーバーヘッドを生む。
その代わりに、スクリプトをHealthと HealthPresenterに分けることから始めて、よりMVP中心の方法でヘルスコンポーネントを書き直すことができます。
サンプル・プロジェクトでは、シューティング・ディスク(ClickDamage.cs)で表現されたターゲット・オブジェクトをクリックしてダメージを与えたり、ボタンでヘルスをリセットすることができます。これらのイベントは、Healthを直接変更するのではなく、HealthPresenter(HealthPresenterは、DamageまたはResetを呼び出します)に通知します。UIテキストとUIスライダーは、Healthがイベントを発生させ、その値が変更されたことをHealthPresenterに通知すると更新されます。
ヘルス・コンポーネントがどのようなものか、さらに深く掘り下げてみよう。このバージョンでは、ヘルスがモデルとなっている。これは実際の健康値を保存し、その値が変化するたびにHealthChangedというイベントを呼び出す。Healthはゲームプレイのロジックを含まず、データのインクリメントとデクリメントを行うメソッドのみである。
これにより、データ、その表示方法、管理方法を明確に区別することができる。
MVP(およびMVC)は、大規模でUIを多用するソフトウェア・アプリケーションで真価を発揮するが、そのようなユースケースに限定されるものではない。ゲームの開発に大規模なチームを必要とし、ローンチ後も長期にわたってゲームを維持することを想定している場合、次のようなメリットが考えられます:
スムーズな仕事の分担: ViewとPresenterを分離したため、ユーザーインターフェイスの開発や更新は、他のコードベースからほぼ独立して行うことができます。あなたのチームにはフロントエンドのエキスパートがいますか?ビューのことは彼らに任せておけばいい。
MVPとMVCによるユニットテストの簡素化: これらのデザインパターンは、ゲームプレイのロジックをユーザーインターフェースから分離する。このように、エディターでプレイ・モードに入らなくても、オブジェクトをシミュレートしてコードを操作することができる。これでかなりの時間を節約できる。
保守可能な読みやすいコード: このデザイン・パターンではクラスを小さくする傾向があり、読みやすくなる。依存関係が少ないということは、通常、ソフトウェアが壊れる場所が少ないということであり、バグが隠れている可能性がある場所が少ないということであり、テストが容易であるということである。
MVCとMVPは、ウェブ開発や企業向けソフトウェアで広く普及しているが、多くの場合、アプリケーションが十分な規模と複雑さに達するまで、その利点は明らかにならない。Unityプロジェクトでどちらのパターンを実装するにしても、事前に以下の点を考慮する必要があります:
前もって計画を立てる必要がある: MVCとMVPは、より大きなアーキテクチャ・パターンである。このうちの1つを使うには、担当ごとにクラスを分ける必要がある。デザイン・パターンは一貫して使用するのがベストなので、UIを整理するためのプラクティスを確立し、チームに浸透させたい。
Unityプロジェクトのすべてがパターンに当てはまるわけではありません: 純粋な」MVCやMVPの実装では、画面にレンダリングするものはすべてビューの一部である。すべてのUnityコンポーネントがデータ、ロジック、インターフェイスに簡単に分割できるわけではありません(例えばMeshRenderer)。また、単純なスクリプトでは、MVC/MVPの恩恵はあまり得られないかもしれない。
そのパターンから最も恩恵を受けられるのはどこかを判断する必要がある。通常は、ユニットテストに導いてもらえばいい。もしMVC/MVPがテストを容易にするのであれば、アプリケーションのその側面でそれらを検討する。そうでなければ、自分のプロジェクトに無理にパターンを当てはめようとしないことだ。
![電子書籍をカバーする拡張性のあるコード・アーキテクチャを作成する](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2Fd9dc90fea539101e4af24bc8d51436b11ab2a8fa-800x450.jpg&w=3840&q=75)
Unityアプリケーションでデザインパターンを使用する方法とSOLIDの原則については、無料の電子書籍に多くのヒントがあります。 ゲームプログラミングパターンでコードをレベルアップ.
Unity UIとUI Toolkitの使い方について、より詳細な説明が必要な場合は、広範なガイドを参照してください、 Unityでのユーザーインターフェイスデザインと実装ガイドを参照してください。
ベストプラクティスハブでは、Unityの高度なテクニカル電子書籍や記事をすべてご覧いただけます。電子書籍は、ドキュメンテーションの上級ベストプラクティスのページでもご覧いただけます。