ゲームサブシステムにゲームオブジェクトコンポーネントを登録しますか? (コンポーネントベースのゲームオブジェクトデザイン)
-
08-10-2019 - |
質問
私はAを作成しています コンポーネントベースのゲームオブジェクトシステム. 。いくつかのヒント:
GameObject
単にのリストですComponents
.- がある
GameSubsystems
. 。たとえば、それぞれレンダリング、物理学などGameSubsystem
いくつかのポインターが含まれていますComponents
.GameSubsystem
非常に強力で柔軟な抽象化です。ゲームの世界のスライス(または側面)を表します。
登録メカニズムには必要です Components
の GameSubsystems
(いつ GameObject
作成されて構成されています)。がある 4つのアプローチ:
- 1: 責任の連鎖 パターン。毎日
Component
すべてに提供されますGameSubsystem
.GameSubsystem
決定を下しますComponents
登録する(およびそれらを整理する方法)。たとえば、GamesubsystemRenderは、レンダリング可能なコンポーネントを登録できます。
プロ。 Components
それらがどのように使用されているかについては何も知りません。低カップリング。 A. 新しい追加できます GameSubsystem
. 。たとえば、すべてのComponentTitleを登録し、すべてのタイトルが一意であり、タイトルごとにクエーリングオブジェクトにインターフェイスを提供するGamesubsystemTitlesを追加しましょう。もちろん、この場合、ComponentTitleを書き直したり継承したりしないでください。 B. 既存を再編成できます GameSubsystems
. 。たとえば、GamesubsystemAudio、GamesubsystemRender、GamesubsystemParticleEmmiterをGameSubSystemSpatialに統合できます(すべてのオーディオ、emmiter、renderを配置するには Components
同じ階層で、親関連の変換を使用します)。
con。すべてのチェック。非常に無効です。
con。 Subsystems
について知る Components
.
- 2:それぞれ
Subsystem
検索Components
特定のタイプの。
プロ。でより良いパフォーマンス Approach 1
.
con。 Subsystems
まだ知っています Components
.
- 3:
Component
登録しますGameSubsystem(s)
. 。コンパイル時にGamesubsystemRendererがあることを知っているので、ComponentImagerenderはGamesubsystemRenderer :: Register(componentrenderbase*)のようなものを呼び出します。
観察者 パターン。Component
「Update」イベントを購読しています(送信GameSubsystem(s)
).
プロ。パフォーマンス。のように不必要なチェックはありません Approach 1
と Approach 2
.
con。 Components
ひどく結合されています GameSubsystems
.
- 4: メディエーター パターン。
GameState
(それが含まれていますGameSubsystems
)RegisterComponent(コンポーネント*)を実装できます。
プロ。 Components
と GameSubystems
お互いについて何も知りません。
con。 C ++では、醜くて遅いTypeIDスイッチのように見えます。
質問:どのアプローチが優れており、ほとんどがコンポーネントベースの設計で使用されていますか?どのような練習は言いますか? (データ駆動型の)実装に関する提案 Approach 4
?
ありがとうございました。
解決
3番目のアプローチに投票してください。
私は現在、コンポーネントベースのゲームオブジェクトシステムに取り組んでいますが、このアプローチの追加の利点のいくつかを明確に確認しています。
コンポーネントは、利用可能なサブシステムのセットにのみ依存するため、ますます自己困難なサブエンティティです(このセットはプロジェクトで修正されていると思います)。
データ駆動型の設計がより適用可能です。理想的には、この方法では、コンポーネントがデータの用語で完全に定義されているが、C ++ではなく定義されているシステムを設計することができます。
編集:CBGOの作業中に考えた機能の1つ。時々、設計と構築を行う能力を持つことができます サブシステムレス パッシブコンポーネント。これがあなたの心にあるとき、4番目のアプローチが唯一の方法です。
他のヒント
私のアプローチは、各サブシステム内にプロキシパターンを実装することでした。各サブシステムは、各エンティティに含まれる総コンポーネントのサブセットにのみ関心を持っているため、プロキシは、システムが気にするコンポーネントのみにポインターを保存します。これらのコンポーネントへの2つのポインター。エンティティにそれらの1つ以上が欠落している場合、サブシステムはそれを無視します。両方のコンポーネントが存在する場合、プロキシノードが作成され、内部コレクションに追加されます。また、プロキシがエンティティの一意の識別子値を保存することも役立ちます。そのため、必要に応じてプロキシが各サブシステムから一定の時間で追加/削除される可能性があります。
そのような方法では、エンティティをエンジンから削除する必要がある場合、エンティティのIDを含む単一のメッセージをすべてのサブシステムに送信できます。プロキシは、各サブシステムコレクションから個別に削除できます。