設計原則¶
SOAR (Scriptable Object Architecture Reactive-extensible) は、単なるツールの集まりではなく、Unity でクリーンで疎結合、かつスケーラブルなアプリケーションを構築するための哲学です。SOAR の背後にある中心的な設計原則を理解することで、より保守しやすく堅牢なコードを書くことができます。
パブリッシャー/サブスクライバーパターン¶
SOAR における最も基本的な原則は、パブリッシャー/サブスクライバー (Pub/Sub) パターンです。これは、次のようなメッセージングパターンです:
- パブリッシャー(またはブロードキャスター)は、どのコンポーネントがメッセージやイベントを受信するかを直接知ることなく、それらを発行します。
- サブスクライバー(またはリスナー)は、どのコンポーネントがイベントを生成するかを知ることなく、特定のイベントに関心を登録します。
- メッセージブローカーまたはイベントチャネルが両者の間を仲介し、コンポーネントを疎結合にします。
SOAR の実装では:
GameEventおよびVariableアセットがイベントチャネルまたはトピックとして機能します。- 任意のスクリプトが、
GameEventのRaise()メソッドを呼び出すか、VariableのValueを変更することでパブリッシャーとして機能できます。 - 任意のスクリプトが、イベントの
Subscribe()を呼び出すか、UnityEventBinderを使用してリッスンすることでサブスクライバーとして機能できます。
このパターンは、疎結合の鍵です。イベントを発生させる UI ボタンは、そのクリックに反応する必要があるオーディオシステム、分析システム、またはゲームロジックへの参照を必要としません。それらはすべて、同じ共有イベントアセットをリッスンするだけです。
依存関係逆転¶
ScriptableObject アセットを通信チャネルとして使用することで、SOAR は依存関係逆転を実現します。高レベルのコンポーネントが低レベルのコンポーネントへの直接参照を持つ(例:GameManager が特定の PlayerHealth スクリプトを知っている)代わりに、両方のコンポーネントが同じ共有 ScriptableObject アセットを参照します。
従来(密結合)のアプローチ:
SOAR(疎結合)のアプローチ:
この逆転は、コンポーネントを分離して開発、テスト、および変更できることを意味します。GameManager をまったく必要とせずに、インスペクターで PlayerHealthVariable を変更するだけで PlayerHealth のロジックをテストできます。
シーン間の通信¶
ScriptableObject は特定のシーンの外部に存在するアセットであるため、シーン間の通信に最適なツールです。「MainMenu」シーンで発生した GameEvent は、両方が同じイベントアセットへの参照を持っている限り、「Level01」シーンのコンポーネントで簡単にリッスンできます。これにより、複雑な DontDestroyOnLoad マネージャーや静的なシングルトンに頼ることなく、一般的な Unity の問題が解決されます。
SOAR を使用したモデルビュープレゼンター (MVP)¶
SOAR は、UI を多用するアプリケーションを構造化する一般的な方法であるモデルビュープレゼンター (MVP) パターンに自然に適合します。
- モデル: アプリケーションの生データとビジネスロジック。純粋な実装では、モデルは Unity を認識すべきではありません。
- ビュー: データを表示する Unity コンポーネント(例:
Text、Slider、Image)。ビューは「ダム」であり、指示された内容を表示する方法しか知りません。 - プレゼンター: モデルとビューの間のメディエーター。モデルの変更をリッスンし、データをフォーマットし、ビューに表示方法を指示します。また、ビューからの入力(ボタンのクリックなど)をリッスンし、モデルを更新します。
SOAR アセットは、モデルとプレゼンターの間の完璧なレイヤーとして機能します:
Variableは、モデルデータの一部をラップできます。- プレゼンターは、この
Variableをサブスクライブします。 - モデルが変更されると、
Variableが更新されます。 - プレゼンターに通知され、ビューコンポーネントが更新されます。