4

私は軽量のゲーム エンジンを作成しており、そのための調査を行っているときに、「具象クラスからの継承」モデルではなく「コンポーネントのコレクション」モデルによるゲーム オブジェクトの実装を提唱する説得力のある記事をいくつか見つけました。多くの利点があります:

  • オブジェクトは、データ駆動型の設計手法を使用して構成できるため、設計者はプログラマーを関与させずに新しいオブジェクトを考え出すことができます。
  • ソースファイルの依存関係が少なくなる傾向があるため、コードをより高速にコンパイルできます。
  • エンジン全体がより一般的になります。
  • 継承階層の上位にある具体的なクラスを変更しなければならないという予期しない結果を回避できます。
  • 等々。

しかし、システムには不透明な部分があります。主に、同じオブジェクトのコンポーネントが相互に通信する方法です。たとえば、ゲーム内の弾丸をモデル化するオブジェクトが、次のコンポーネントに関して実装されているとします。

  • 視覚的表現のためのジオメトリのビット
  • 世界での地位
  • 他のオブジェクトとの衝突に使用されるボリューム
  • 他のもの

レンダリング時に、正しく表示するためにジオメトリはワールド内での位置を認識している必要がありますが、オブジェクト内のすべての兄弟コンポーネント間でその位置をどのように見つけるのでしょうか? また、更新時に、他のオブジェクトとの交差をテストするために、コリジョン ボリュームはどのようにしてワールド内のオブジェクトの位置を見つけるのでしょうか?

私の質問は次のように要約できると思います: さて、それぞれが少しの機能を実装する多数のコンポーネントで構成されるオブジェクトがあります。これが実行時に機能するための最良の方法は何ですか?

4

7 に答える 7

1

私はこれを実装するいくつかの方法を見てきました(そして試しました):

1)コンポーネントは真空状態では存在しませんが、「エンティティ」(または「ゲームオブジェクト」)オブジェクトに収集されます。すべてのコンポーネントにはエンティティへのリンクがあるため、衝突はGetEntity()-> GetComponent( "Position")-> GetCoords()(おそらくヌルベクトルなどをチェックします-詳細は言語によって異なります)のようになります。再作業)。

この場合、いくつかの一般的な情報(位置、一意のID、「アクティブ/非アクティブ」ステータス)をエンティティに直接配置すると便利な場合があります。「純粋な」ものと一般的なものを作成することと、何かを迅速に作成することの間にはトレードオフがあります。効率的です。

2)エンティティはなく、コンポーネントのみです(私はこれを自分の軽量ゲームエンジンに使用しています)。この場合、コンポーネントは他のコンポーネントに明示的にリンクする必要があるため、「衝突」と「グラフィックス」が「位置」へのポインタを保持する可能性があります。

于 2008-11-04T14:35:08.617 に答える
1

コンポーザブル アーキテクチャは通常、インターフェイスに依存します。コンポーネントは実装+データであり、設計者は利用可能な実装を異なるデータで再利用できます。たとえば、ロケットのコードをロケットのグラフィックで 1 回、矢印のグラフィックで 1 回使用します。柔軟性は、実際の実行時間外でそのような組み合わせを「構成」できることからもたらされます。

ランタイム内で、オブジェクトはインターフェイスを介して必要な情報を受け取り、提供します。たとえば、オブジェクトは原点と参照方向を受け取り、ワールド内で自身を配置します。実際に描画する場合は、一種のグラフィック コンテキストが渡され、インフラストラクチャが現在のオブジェクトに合わせてデフォルトのオフセット/プロジェクションを適切に調整すると仮定します。

于 2008-10-14T18:18:24.990 に答える
1

私はいつも、Kyle Wilson のブログが、これに取り組んでいて、多くのことを考えている人からの興味深い情報源であることを発見しました. 特に、このエントリは興味深いかもしれません: http://gamearchitect.net/2008/06/01/an-anatomy-of-despair-aggregation-over-inheritance/ . それは記事のキーポイントではありませんが、基本的に彼が言っていることは、(' Fracture ' を開発している間) 別々の階層を持っていたということです。1 つは GameObjects 用で、1 つは視覚的表現用の SceneGraph です。個人的には非常に健全な設計だと思いますが、私はこの分野の専門家ではありません。

于 2008-11-12T11:10:05.517 に答える
1

この戦略を追求するもう 1 つの大きな理由は、ビヘイビア コンポーネントからオブジェクトのビヘイビアを構成できることです。これにより、複数のゲーム オブジェクト間でビヘイビアを再利用できます。

たとえば、次のプロパティを持つ基本的なゲーム オブジェクト クラスがあるます。デフォルトでは、それぞれが null への参照を保持します。オブジェクトを燃焼可能にしたい場合は、次のように設定します。

object.burnable = new Burnable(object);

さて、オブジェクトを焼きたいときはいつでも、次を使用してください:

if (object.burnable != null)
{
   object.burnable.burn();
}

また、焼き付け可能な動作は、ゲーム オブジェクトを任意の方法で変更します。

于 2008-10-15T15:55:22.967 に答える
0

私もこれを研究しており、高速で邪魔にならないソリューションをいくつか考え出しました。

コンポーネントベースのアプリケーションを使用する目的は、実行時にいつでもコンポーネントを追加および削除でき、結合がほとんどまたはまったくないことです。コンポーネントは、お互いを知らなくても共存できます。

では、「レンダリング」コンポーネントは、レンダリングする場所やさらに悪いことに、何をレンダリングする必要があるかをどのように判断するのでしょうか? 私の答えは、各兄弟コンポーネントは、コンテナー (通常はゲーム エンティティまたはゲーム オブジェクト) が保持するプロパティの共有テーブルにアクセスできるということです。

たとえば、動きコンポーネント、レンダリング コンポーネント、キャラクター コンポーネントを持つゲーム オブジェクトを想定します。

レンダリング コンポーネントは、コンテナーに "positionx"、"positiony"、"positionz" (3D ゲームの場合) という名前のプロパティを要求し、次に "rendermodel" プロパティを要求します。それらに基づいて、レンダラー コンポーネントは、rendermodel によって返されたプロパティを positionx、positiony、および positionz でレンダリングします。配置プロパティは移動コンポーネントによって変更され、それ自体がコンテナの「速度」プロパティを要求し、キーボード入力に基づいて文字コンポーネントによって調整されます。

これらのプロパティが存在しない場合は、要求された時点で作成され、有効な値 (例: 0) で初期化されます。

私の見解では、コンポーネントは他のコンポーネントに対してクエリを実行するべきではありません。コンポーネントは可能な限り汎用的に見なされる必要があるためです。

于 2011-04-16T19:07:14.910 に答える
0

オブジェクトに Game オブジェクトへの参照を戻すことは可能でしょうか?

これにより、Game オブジェクトに戻ってワールド位置にドリルダウンすることで、ワールド位置を見つけることができます。

于 2008-10-14T18:20:42.347 に答える
-1

少し過剰に設計されているように聞こえます。場所を基本的なプロパティではなくオブジェクトの抽象的なコンポーネントにすることで、何を得ることができますか?

しかし、本当にそのようにしたい場合は、すべてが明示的に接続されているディペンデンシー グラフを設定できると思います。したがって、(例) 衝突ボリュームには、位置コンポーネントの出力に接続された位置入力があります。Maya の内部を見て、これがどのように機能するかを理解してください。

しかし、繰り返しになりますが、これはやり過ぎのように見えます。

于 2008-10-14T18:20:20.320 に答える