
Unity ScriptableObjectsデモの使用を開始する
このページでは、eBook『Create modular game architecture in Unity with ScriptableObjects』のコンパニオンデモ プロジェクトであるPaddleBallSOの概要と、それがコード アーキテクチャでデザイン パターンとモジュール性をどのように使用しているかを説明します。
これは、e ブックに付属するデモで Unity 開発者を支援するために作成された 6 つのミニガイドシリーズの第 1 弾です。このデモは、古典的なボールとパドルを使ったアーケードゲームメカニクスに着想を得たもので、ScriptableObject がテスト可能でスケーラブル、かつデザイナーにとって使いやすいコンポーネントの作成にどのようにヘルプつかを示しています。
この e ブック、デモプロジェクト、およびこれらのミニガイドは、プログラミングデザインパターンを Unity プロジェクトで ScriptableObject クラスと併用するためのベストプラクティスを提供します。これらのヒントは、コードを簡素化し、メモリ使用量を削減し、コードの再利用性を促進するのにヘルプます。
このシリーズには、次の記事が含まれています。
開始前の重要事項
ScriptableObject デモプロジェクトとこのミニガイドシリーズを掘り下げる前に、その中核をなすデザインパターンは単なるアイデアに過ぎないことを覚えておいてください。すべての状況に当てはまるわけではありません。これらのテクニックは、Unity と ScriptableObject の新しい使い方を学ぶのにヘルプます。
それぞれのパターンには長所と短所があります。特定のプロジェクトにとって意味のあるものだけを選びましょう。デザイナーは Unity エディターに大きく依存していますか?ScriptableObject ベースのパターンは、開発者とのコラボレーションのヘルプに適しています。
結局のところ、最高のコードアーキテクチャは、皆さんのプロジェクトやチームに合ったものです。

パドルボール ScriptableObject プロジェクト
PaddleBallSO は、2 人のプレイヤー、2 つのパドル、1 つのボールが登場する、最新のビデオゲームを生み出したクラシックゲームを中心にしています。
ここでは、ゲームメカニクスよりもインフラストラクチャに重点を置いています。これは「ゲーム 配管」と考えてください。アプリケーションの実行を維持するうえで、華やかさは劣るものの非常に重要です。
このプロジェクトでは、ScriptableObject を裏で動作させて統合アプリケーションをビルドする方法に焦点を当てます。これを使用して、プロジェクトメンテナンスを簡素化し、コードの再利用性を促進する、汎用性の高いゲームシステムを構築できます。また、プレイヤーデータ、ゲームステート管理、ゲーム内動作などにも使用できます。
PaddleBallSOプロジェクトは、最新バージョンのUnity長期サポート(LTS)、現在2022 LTSと互換性のあるプロジェクトです。ランタイム UI を作成するための UI Toolkit とユーザー入力を処理する Input System が組み込まれています。

スタートガイド
GitHub リポジトリでプロジェクトを探してダウンロードします。
Bootloader_scene をロードするか、「GameSystems」メニューから「Load Bootstrap Scene on Play」を有効にします。再生モードを開始してください。
これらは ScriptableObject に固有のものではありませんが、デモプロジェクトでは、一貫性のある予測可能な状態でゲームアプリケーションを開始するヘルプとして、いくつかの一般的なテクニックを使用しています。
Scene Bootstrapper(またはブートローダー)は、ゲームの初期状態を設定するエディター拡張子スクリプトです。この初期化コードはゲームロジックから分離されており、シーン内のオブジェクトに対するすべての依存関係が正しく設定されます。
依存関係の問題を回避するために、Boottrapper はシーンのロード時に重要なゲームオブジェクト、マネージャー、またはサービスを設定します。
Unityアプリケーションが複数のシーンにまたがる場合、ブートローダーは特定のブートストラップシーンを強制的にロードできます。これはビルド設定の最初のシーンです。再生モードを終了すると、前のシーンが再ロードされます。
ブートストラップシーンの別のコンポーネントである Sequence Manager は、シーンロード時に必須のプレハブをインスタンス化できます。このデモプロジェクトでは、カメラ、スプラッシュスクリーン、UI メニュー、SceneLoader など、ゲームの作成に必要なすべてがプレハブです。
その後、SceneLoader は必要に応じてゲームプレイシーンを追加的にロード (およびアンロード) します。ほとんどの場合、これらのシーンは主にプレハブで構成されます。
プロジェクトシーン
各ミニゲーム レベルは個別のUnityシーンであり、ビルド設定に表示されます。個々のシーンを探る場合は、「GameSystems」メニューで SceneBootstrapper を無効にします。
多くのプロジェクトには、ブートストラップシーンの後にメインメニュー用のステージング領域もあります。この簡略化されたデモプロジェクトでは、メインメニューシーンが省略されています。

PaddleBallSO プロジェクトの概要
「Play」メニューと「Pattern」メニューを使用して、次の PaddleBallSO をテストします。
- 具体的なテクニックを示し、各パターンを個別に示すデザインパターンのデモまたは簡単な例
- これらを組み合わせて機能するサンプルを作成するミニゲーム
Core フォルダーには、基本パターンスクリプト、シーン管理、UI ロジックなど、コードベースのアプリケーション固有ではない部分が含まれます。これらは、さまざまなアプリケーションに適用できる、より一般的なクラスです。

パターンとミニゲームを探る
サンプルゲームでは、代表的な 2D 物理シミュレーションを再現し、ScriptableObject ベースのデザインパターンの可能性を紹介しています。
ただし、パターンについて説明する前に、アプリケーションを構成する MonoBehaviour について理解しておく必要があります。ご想像の通り、Paddle、Ball、Bouncer、ScoreGoal スクリプトなどのコンポーネントが基本的なゲームプレイを制御します。
ゲームフローを制御するいくつかの上位レベルのマネージャースクリプト:
- GameManger は、ゲームの状態 (開始、終了、リセット) を制御し、ゲームコンポーネントの初期化、UI の管理、イベントへの応答を行います。
- GameSetup は GameManager と連携して、ボール、パドル、壁、ゴールを設定します。
- ScoreManager はスコア値を更新し、ゲームイベントを処理し、スコア表示の UI 更新を制御します。
これらの MonoBehaviour は ScriptableObject と連動します。これらのコンポーネントを橋渡しして、コンポーネント間で通信およびデータ共有できるようにする重要な役割を果たします。
イベントは、プロジェクトのさまざまな部分間のコミュニケーションに役立ちます。これらのマネージャースクリプトを、ほかのシーンオブジェクトやユーザーインターフェースと接続します。このイベント駆動型のアーキテクチャは、コードをより整理してデバッグしやすくするのにヘルプます。
また、最も一般的な ScriptableObject パターンごとに簡略化されたデモ例も提供しています。ScriptableObject に慣れると、ミニゲームのアーキテクチャを支える ScriptableObject の理解を開始できます。
もっと少ないコード行で、注目のミニゲームを作ることもできましたが、このデモでは特に ScriptableObject を使ったデザインパターンに焦点を当てています。これらのパターンの多くは、ScriptableObject なしでも実装できます。
チームで各パターンをプロジェクトにどのように適用するかを決め、自分に最も適したアプローチを選択します。

モジュラー型ゲームアーキテクチャ
ソフトウェア開発のモジュール性には、アプリケーションをより小さく独立した部分に分割することが含まれます。これらのモジュールは特定の目的に適しており、個別に開発およびテストできます。
各小さなオブジェクトセットは 1 単位として機能し、ゲームの 1 つの側面を処理します。これには、プレイヤー入力の制御、物理演算の処理、スコアの集計などが含まれます。
プロジェクトスクリプトを探るする際には、以下のキーなポイントに注意してください。
- プレハブからシーンを構築する:プロジェクト内のほとんどのシーンは、オーバーライドを最小限に抑えた単純なプレハブの Collections です。プレハブは本質的にある程度のモジュール性を提供します。 特徴のトラブルシューティングは、そのプレハブを単独でテストする作業になります。ScriptableObject と同様に、プレハブは複数のシーンで再利用して共有できるプロジェクトレベルのアセットです。
- データ ストレージにScriptableObjectを使用(その他):MonoBehaviour を使用して静的ゲームプレイ データを保存しない。代わりに、ScriptableObject を活用して再利用性を高めましょう。 また、特定のゲームロジックを ScriptableObject に任せたり、シーンオブジェクト間の通信を容易にしたりすることもできます。
- 個別の懸念事項:プロジェクト内のデータ、ロジック、ユーザーインターフェースの消去。これにより、コードの保守性が向上し、デバッグが簡単になります。 メニュー画面システムは、新しい UI Toolkit を使用しています。この UI システムは、その基盤となるロジックからインターフェースを分離するワークフローを適用します。詳細については、eBook「ユーザー インターフェースの設計とUnityでの実装」を参照してください。
- 依存関係の最小化:コンポーネント間の依存関係を減らすことで、予期せぬ問題を引き起こすことなく、プロジェクトの一部の変更や置き換えが容易になります。
- コミュニケーションにイベントを使用する:イベントはコンポーネント間の疎結合を可能にし、直接依存することなく互いにメッセージを送信できるようにします。さらに、ScriptableObject ベースの「イベントチャンネル」で切り離すこともできます。
- 不要なシングルトンを避ける:シングルトンデザインパターンは便利ですが、クラスのインスタンスが 1 つだけ必要な場合に限られます。シングルトンを使いすぎると、コードが密結合になり、テストに支障を結果可能性があります。不要な場合はシングルトンをスキップします。
大きなモノリシックスクリプトを小さなピースにリファクタリングすることで、再利用性とスケーラビリティビリティが向上します。これにより、チームのコラボレーションが向上し、テストが簡素化されます。

ScriptableObject の使用
ScriptableObject のユースケースを実演するために、PaddleBallSO プロジェクトを作成しました。ここでは、これらのツールのアクションを実際に目にする具体的な場所をいくつか紹介します。
- GameDataSO ScriptableObject は、ゲーム設定の中央データコンテナとして機能します。共通データを 1 回編集し、それを必要な他のオブジェクトと共有します。
- ミニゲームでは、多数のイベントチャンネルを使用して、切り離された形で通信が行われます。これらの ScriptableObject ベースのイベントは、オブジェクトが互いにメッセージを送信する方法のバックボーンを形成します。
- サウンド再生では、ScriptableObject ベースのデリゲートオブジェクトを使用して、ロジックを MonoBehaviour コンポーネントから分離します。
- PlayerIDSO ScriptableObjectベースのenumを使用して、Player1とPlayer2の「チーム」を区別します。
- LevelLayoutSO ScriptableObject は、パドル、ゴール、壁、ボールなどのゲーム要素の開始位置のデータコンテナとして機能します。 これにより、Unity 内およびエクスポートされた JSON ファイルを介して外部でレベルのレイアウトを簡単に変更できるようになります。Unity 以外でレベルデザインを改造することで、プレイヤーの創造性を高め、カスタムレイアウトを共有できます。
デザインパターンのデモもぜひご覧ください。

ScriptableObject に関する 6 つのベストプラクティス
ScriptableObjectは、ゲームデータを保存し、ワークフローを効率化するための強力なツールですが、プロジェクトを乱雑にしないためには、それらを効果的に使用することが不可欠です。
UnityでScriptableObjectを使用するためのベストプラクティスをいくつか紹介します。
- データをモジュール化して整理する:異なるデータ(例:プレイヤーの統計情報用、敵の動作用など)に別々の ScriptableObject を使用します。複雑なデータを簡単にマネージできる小さなデータに分割します。
- フォルダと命名規則を使用する:ScriptableObject はスクリプトのコードを減らすのにヘルプますが、そのトレードオフはプロジェクトフォルダー内のより多くのアセットを扱うことです。適切な命名とディレクトリ構成は、これらの ScriptableObject を効率的に管理するのにヘルプます。命名に関するヒントについては、コードスタイルガイドをご覧ください。
- ScriptableObject の過剰な使用を避ける:ScriptableObjectは素晴らしいデータ コンテナーですが、使いすぎないことが重要です。ScriptableObject はプロジェクトを複雑にする可能性があるので、メリットを消去できる場合にのみ導入してください。(例えば、永続データの保存には使用しないでください)。
- データを定期的にバックアップする:ScriptableObject への変更はランタイムで「ライブ」に行われ、アセットファイルとして保存されます。データが失われないように、プロジェクトの定期的なバックアップを取るようにしてください。Version Controlソフトウェアを使用して、ScriptableObject への変更を追跡します。
- Inspector ウィンドウを使用します。ScriptableObject の主な利点の 1 つは、シリアライズ可能で Inspector に表示されることです。ScriptableObject に保存されているデータをビューおよび操作するには、エディターインターフェースを利用します。
- カスタムエディタースクリプトを使用して、ScriptableObject は、シーン階層のランタイムオブジェクトをネイティブに参照できません。これらのオブジェクトを視覚化する必要がある場合は、エディタースクリプトを使用して Inspector をよりユーザーフレンドリーなインターフェースにできます。
これらのガイドラインに従うことで、よくある開発上の落とし穴を回避できます。

その他の ScriptableObject リソース
ScriptableObject を使ったデザインパターンの詳細については、e ブック「Create modular game アーキテクチャ in Unity with ScriptableObjects」をお読みください。また、一般的な Unity 開発のデザインパターンについては、e ブック「Level up your コード with game programming patterns」をご覧ください。