タグ付けされた質問 「entity-system」

ゲームオブジェクト(エンティティ)がコンポーネントから構成され、システムによって操作されるプログラミングパラダイム。各エンティティは、特定のコンポーネントを指すIDです。

3
同じコンポーネントセットのエンティティを線形メモリにグループ化する
基本的なシステム、コンポーネント、エンティティのアプローチから始めます。 コンポーネントのタイプに関する情報だけから集合(この記事から派生した用語)を作成しましょう。これは、エンティティにコンポーネントを1つずつ追加/削除するのと同じように、実行時に動的に行われますが、タイプ情報のみを対象としているため、より正確に名前を付けましょう。 次に、それらすべての集合を指定するエンティティを作成します。エンティティを作成すると、その組み合わせは不変です。つまり、その場で直接変更することはできませんが、ローカルコピーへの既存のエンティティの署名を(コンテンツとともに)取得し、適切に変更して、新しいエンティティを作成できます。それの。 ここで重要な概念について説明します。エンティティが作成されると、それは常にassemblage bucketというオブジェクトに割り当てられます。つまり、同じ署名のすべてのエンティティが同じコンテナ(例:std :: vector)に置かれます。 現在、システムは関心のあるすべてのバケットを反復処理し、その仕事をしています。 このアプローチにはいくつかの利点があります。 コンポーネントは少数(正確にはバケット数)の連続したメモリチャンクに格納されます-これによりメモリの使いやすさが向上し、ゲーム全体の状態をダンプするのが簡単になります システムはコンポーネントを線形的に処理します。つまり、キャッシュの一貫性が向上します。さようなら辞書とランダムメモリジャンプ 新しいエンティティの作成は、アセンブリをバケットにマッピングし、必要なコンポーネントをそのベクトルにプッシュバックするのと同じくらい簡単です エンティティの削除は、std :: moveを1回呼び出して最後の要素を削除された要素と交換するのと同じくらい簡単です。現時点では順序は関係ないためです。 完全に異なるシグネチャを持つ多くのエンティティがある場合、キャッシュコヒーレンシの利点はある程度減少しますが、ほとんどのアプリケーションでは発生しないと思います。 ベクトルが再割り当てされると、ポインターの無効化にも問題があります。これは、次のような構造を導入することで解決できます。 struct assemblage_bucket { struct entity_watcher { assemblage_bucket* owner; entity_id real_index_in_vector; }; std::unordered_map<entity_id, std::vector<entity_watcher*>> subscribers; //... }; そのため、ゲームロジックの何らかの理由で、新しく作成されたエンティティを追跡したいときはいつでも、バケット内にentity_watcherを登録し、エンティティを削除中にstd :: moveする必要がある場合は、そのウォッチャーをルックアップして更新しますそれらreal_index_in_vectorを新しい値に。ほとんどの場合、これはエンティティの削除ごとに1回の辞書検索を課します。 このアプローチには他に不利な点はありますか? なぜ明白なのに、なぜ解決策がどこにも言及されていないのですか 編集:コメントが不十分であるため、「回答に答える」ために質問を編集しています。 静的なクラスの構築を回避するために特別に作成された、プラグ可能なコンポーネントの動的な性質を失います。 私はしません。多分私はそれを十分に明確に説明しなかった: auto signature = world.get_signature(entity_id); // this would just return …

2
エンティティ/コンポーネントベースのシステムでゲームの状態を構造化する方法
ここで説明するように、コンポーネント間の通信にシステムを使用するエンティティコンポーネントパラダイムで設計されたゲームを作成しています。開発の段階で、ゲームの状態(一時停止、再生、レベルスタート、ラウンドスタート、ゲームオーバーなど)を追加する必要がありますが、フレームワークでそれを行う方法がわかりません。私は誰もが参照していると思われるゲームの状態に関するこのコード例を見てきましたが、私のフレームワークに適合しないと思います。各州が独自の描画と更新を処理しているようです。私のフレームワークには、システムを使用してすべての更新を処理するSystemManagerがあります。たとえば、次は私のRenderingSystemクラスです。 public class RenderingSystem extends GameSystem { private GameView gameView_; /** * Constructor * Creates a new RenderingSystem. * @param gameManager The game manager. Used to get the game components. */ public RenderingSystem(GameManager gameManager) { super(gameManager); } /** * Method: registerGameView * Registers gameView into the RenderingSystem. * @param gameView …

1
自作のレンダリングシステムにリソースをキャッシュする方法
バックグラウンド: 私は、C ++とOpenGLを使用して、エンティティコンポーネントシステムタイプアーキテクチャ用のシンプルな3Dレンダリングシステムを設計しています。システムは、レンダラーとシーングラフで構成されています。レンダラーの最初の反復を終えたら、シーングラフをECSアーキテクチャーに配布します。今のところ、それは何らかの方法でプレースホルダーです。可能であれば、レンダラーの目標は次のとおりです。 シンプルさ。これは研究プロジェクト用であり、システムを簡単に変更および拡張できるようにしたい(したがって、ECSアプローチ)。 パフォーマンス。私のシーンには、多くの小さなモデルと、多くのジオメトリを持つ大きなボリュームがあるかもしれません。OGLコンテキストからオブジェクトを取得し、レンダリングフレームごとにジオメトリをバッファリングすることはできません。キャッシュミスを回避するために、データの局所性を目指しています。 柔軟性。スプライト、モデル、ボリューム(ボクセル)をレンダリングできる必要があります。 分離。レンダラーを作成した後、シーングラフがコアECSアーキテクチャにリファクタリングされる場合があります。 モジュラー。シーングラフを変更せずに、さまざまなレンダラーを入れ替えることができると便利です。 参照透明度、つまり、いつでも有効なシーンを指定できるため、そのシーンでは常に同じ画像がレンダリングされます。特にこの目標は必ずしも必要ではありません。シーンのシリアル化を簡略化し(シーンの保存と読み込みができるようにする必要があります)、テスト/実験の目的で実行時に異なるシーンを入れ替える柔軟性が得られると思いました。 問題とアイデア: 私はいくつかの異なるアプローチを考え出しましたが、各レンダリングノードのOGLリソース(VAO、VBO、シェーダーなど)をキャッシュする方法に苦労しています。以下は、これまでに考えてきたさまざまなキャッシングの概念です。 一元化されたキャッシュ。各シーンノードにはIDがあり、レンダラーにはIDをレンダリングノードにマップするキャッシュがあります。各レンダーノードには、ジオメトリに関連付けられたVAOとVBOが含まれています。キャッシュミスはリソースを取得し、ジオメトリをキャッシュ内のレンダーノードにマップします。ジオメトリが変更されると、ダーティフラグが設定されます。レンダラーがシーンノードを反復処理しているときにダーティジオメトリフラグを確認すると、レンダラーを使用してデータを再バッファーします。シーンノードが削除されると、イベントがブロードキャストされ、レンダラーは関連するレンダーノードをキャッシュから削除し、リソースを解放します。または、ノードに削除のマークが付けられており、レンダラーがノードを削除する責任があります。このアプローチは、4と5も考慮しながら、最も厳密に目標6を達成すると思います。2は、配列アクセスの代わりにマップルックアップを使用すると、複雑さが増し、データの局所性が失われます。 分散キャッシュ。上記と同様ですが、各シーンノードにはレンダーノードがあります。これにより、マップルックアップがバイパスされます。データの局所性に対処するために、レンダーノードをレンダラーに保存できます。その場合、シーンノードは代わりにレンダリングノードへのポインターを持つことができ、レンダラーはポインターをキャッシュミスに設定します。この種のエンティティコンポーネントアプローチを模倣しているので、アーキテクチャの他の部分と一貫性があると思います。ここでの問題は、シーンノードがレンダラー実装固有のデータを保持することです。レンダラでのレンダリング方法を変更する場合(スプライトとボリュームのレンダリングなど)、レンダーノードを変更するか、シーンノードに「コンポーネント」を追加する必要があります(つまり、シーングラフも変更します)。プラス面では、これは、最初の反復レンダラーを起動して実行する最も簡単な方法のようです。 分散メタデータ。レンダラーキャッシュメタデータコンポーネントは、各シーンノードに格納されます。このデータは実装固有ではなく、ID、タイプ、およびキャッシュに必要なその他の関連データを保持しています。次に、IDを使用して配列内で直接キャッシュルックアップを実行できます。タイプは、使用するレンダリングアプローチのタイプ(スプライトとボリュームなど)を示します。 訪問者+分散マッピング。レンダラーはビジターであり、シーンノードはビジターパターンの要素です。各シーンノードは、レンダラーのみが操作するキャッシュキー(メタデータのようにIDのみ)を保持します。IDは、一般化されたマップ検索の代わりに配列に使用できます。レンダラーを使用すると、シーンノードのタイプに基づいてシーンノードが異なるレンダリング関数をディスパッチでき、IDは任意のキャッシュで使用できます。デフォルトまたは範囲外のIDは、キャッシュミスを示します。 この問題をどのように解決しますか?それとも何か提案はありますか?私のテキストの壁を読んでくれてありがとう!

4
エンティティコンポーネントシステムでのエンティティの「タイプ」の識別
エンティティに明示的な「タイプ」(例:プレーヤー)がなく、単にコンポーネントのコレクションである場合、システムで作業する必要があるエンティティとそうでないエンティティを識別するにはどうすればよいですか?たとえば、ポンのゲームでは、パドルとボールの両方がウィンドウの境界に衝突します。ただし、それぞれの衝突処理システムは異なるため、システムは間違ったタイプのエンティティを処理するべきではありません。 void PlayerCollisionSystem::update(std::vector<Entity *> entities) { typedef std::vector<Entity *>::iterator EIter; for (EIter i = entities.begin(); i != entities.end(); ++i) { Entity *player = *i; // How do I verify that the entity is a player? // Get relevant components. PositionComponent *position = player->getComponent<PositionComponent>(); VelocityComponent *velocity = player->getComponent<VelocityComponent>(); SpriteComponent *sprite = …

3
コンポーネントベースのゲームでエンティティの状態とアニメーションを更新するにはどうすればよいですか?
学習目的で(後で一部のゲームで使用するため)コンポーネントベースのエンティティシステムを設計しようとしていますが、エンティティの状態の更新に関して問題が発生しています。 コンポーネント間の依存関係を防ぐために、コンポーネント内にupdate()メソッドを含めたくありません。 私が現在考えているのは、コンポーネントがデータを保持し、システムがコンポーネントを更新することです。 したがって、Transform、Movement、State、Animation、Renderingの各コンポーネントを持ついくつかのエンティティ(たとえば、player、enemy1、enemy2)を含む単純な2Dゲームがある場合、次のようにする必要があります。 すべてのMovementコンポーネントを移動し、Stateコンポーネントを更新するMovementSystem また、アニメーションコンポーネントを更新するRenderSystem(アニメーションコンポーネントは、状態ごとに1つのアニメーション(つまり、フレーム/テクスチャのセット)を持つ必要があり、それを更新することは、現在の状態に対応するアニメーション(jumping、moving_leftなど)を選択することを意味します。フレームインデックスの更新)。次に、RenderSystemは、Renderコンポーネントを各エンティティのアニメーションの現在のフレームに対応するテクスチャで更新し、すべてを画面にレンダリングします。 Artemisフレームワークのようないくつかの実装を見てきましたが、この状況を解決する方法がわかりません。 私のゲームに次のエンティティがあるとします。各エンティティには、一連の状態と、状態ごとに1つのアニメーションがあります。 プレーヤー:「アイドル」、「移動」、「ジャンプ」 enemy1:「moving_up」、「moving_down」 enemy2: "moving_left"、 "moving_right" 各エンティティの現在の状態を更新するために最も受け入れられているアプローチは何ですか?考えられる唯一のことは、エンティティのグループごとに個別のシステムを持ち、状態コンポーネントとアニメーションコンポーネントを個別に持つことです。そのため、PlayerState、PlayerAnimation、Enemy1State、Enemy1Animation ... PlayerMovementSystem、PlayerRenderingSystem ...がありますが、これは悪いことだと思いますソリューションとコンポーネントベースのシステムを持つ目的を壊します。 ご覧のように、私はここでかなり迷っていますので、どんな助けにも感謝します。 編集:私が意図したとおりにこの作業を行うための解決策はこれです: すべてのエンティティに使用できるように、statecomponentとanimationcomponentを十分に汎用的にします。それらに含まれるデータは、再生されるアニメーションや使用可能な状態などを変更するための修飾子になります。–バイト56 今、私はこれらの2つのコンポーネントを再利用できるように十分に汎用的に設計する方法を理解しようとしています。各状態(ウォーキング、ランニングなど)のUIDを持ち、この識別子でキー設定されたAnimationComponentにマップ内のアニメーションを格納することは良いソリューションでしょうか?

4
エンティティシステムとレンダリング
わかった、これまで私が知っていること。エンティティには、次のような情報を保持するコンポーネント(データストレージ)が含まれています。-テクスチャ/スプライト-シェーダー-など そして、これをすべて描画するレンダラーシステムがあります。しかし、私が理解していないのは、レンダラーの設計方法です。「ビジュアルタイプ」ごとに1つのコンポーネントが必要ですか。シェーダーなしのコンポーネント、シェーダー付きのコンポーネントなど これを行うための「正しい方法」についての入力が必要です。注意すべきヒントと落とし穴。

3
コンポーネントエンティティシステム-更新と呼び出し順序
コンポーネントがすべてのフレームを更新できるようにする(そしてこの機能を必要のないコンポーネントから除外する)ために、UpdateComponentコンポーネントを作成するというアイデアを得ました。MovableComponent(速度を保持する)などの他のコンポーネントは、IUpdatable抽象クラスを継承します。これによりMovableComponent、Update(gametime dt)メソッドへのポインタとへのポインタをRegisterWithUpdater()提供するメソッドの実装が強制されUpdateComponentますMovableComponent。多くのコンポーネントがこれを実行し、誰が何であるかを気にすることなくUpdateComponent、すべてのUpdate(gametime dt)メソッドを呼び出すことができます。 私の質問は: これは、正常または誰かが使用しているもののように見えますか?この件については何も見つかりません。 物理学などのコンポーネントの順序を変更してから位置を変更するにはどうすればよいですか?これも必要ですか? フレームごとに処理する必要があるコンポーネントが実際に処理されることを保証する他の方法は何ですか? 編集 私はエンティティマネージャに更新可能なタイプのリストを与える方法を検討していると思います。次に、そのタイプのすべてのコンポーネントを、エンティティごとに管理するのではなく更新できます(とにかく、私のシステムのインデックスにすぎません)。 まだ。私の質問は引き続き有効です。これが理にかなっているのか、通常のことなのか、他の人が何をする傾向があるのか​​はわかりません。 また、不眠症の人々は素晴らしいです! /編集 前の例のコードを煮詰めました: class IUpdatable { public: virtual void Update(float dt) = 0; protected: virtual void RegisterAsUpdatable() = 0; }; class Component { ... }; class MovableComponent: public Component, public IUpdatable { public: ... virtual void Update(float dt); private: ... …

3
エンティティを集約として作成する
私は最近、エンティティを動作から分離する方法と、この記事にリンクされている主な回答について尋ねました:http : //cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ ここで書かれている究極のコンセプトは、純粋な集合体としてのオブジェクトです。 C#を使用してゲームエンティティを純粋な集約として作成する方法を知りたいのですが。これがどのように機能するかという概念はまだよく理解していません。(おそらく、エンティティは特定のインターフェースまたは基本タイプを実装するオブジェクトの配列ですか?) 私の現在の考え方には、関連するインターフェイス(IMoveable、ICollectable、ISpeakableなど)を実装する各エンティティタイプの具象クラスがまだ含まれています。 エンティティの具体的なタイプを持たずに、純粋に集約としてエンティティを作成するにはどうすればよいですか?

1
エンティティコンポーネントシステムにグローバルコンテキストデータをどのように保存しますか?
私の質問はこれです: グローバルコンテキストデータをどのように保存しますか。エンティティコンポーネントシステムの世界データ情報、現在の世界時間など? ドワーフフォートレススタイルのオープンエンドの世界シミュレーションゲームをC ++で構築することを考えています。私は楽しみのためにエンティティコンポーネントスタイルのゲームエンジンを構築しました。現在、必要なすべての機能でどのように機能するかを考えています。標準のゲームプレイ(レンダリング、物理、エンティティ固有のコンポーネントデータなど)に加えて、関連するすべてのシステムがアクセスできるグローバルコンテキストデータ(つまり、現在の年などの世界データ)も必要です、地球温暖化が起こっているかどうか、世界のシミュレーションに関連するあらゆる種類の事柄)。私はもともと「ワールド」コンポーネントを作ることを考えていましたが、多くの異なるシステムがこの論理的に「グローバル」なデータにアクセスする必要がある場合、これは無意味で難しいように見えます。 「ワールド」コンポーネントがあるのは理にかなっているでしょうか、それともこのデータを他の方法で保存すべきでしょうか? また、このデータを単にグローバルにして、それを使用したいすべてのシステムにアクセスできるようにすることも考えました。一般的にはエンティティコンポーネントの原則に違反しているように見えますが、他の理由で混乱しているようですが、実際に機能する可能性があると思いました。 私が考えたもう1つのことは、関連するワールドコンテキストデータをシステム自体に直接埋め込むことです。たとえばAgeSystem、getsWeakerAsTimePassesコンポーネントがあるかどうかに関係なく、すべてのエンティティが「古くなった」場合、おそらくこのシステムは、世界の関連する時間データをメンバーデータとして直接保存し、時間の経過とその量を計算するために使用できます。この3つ目のオプションは、私のお気に入りではありませんでしたが、ブレーンストーミングで思いついたことがあります。 誰かアドバイスできますか?

3
エンティティコンポーネントシステムで「ブロブシステム」を回避する方法
現在、私は次の問題に直面しています: エンティティコンポーネントシステム(ECS)を使用してポンクローンを作成しようとしています。「フレームワーク」はすべて自分で書きました。したがって、すべてのコンポーネントでエンティティを管理するクラスがあります。次に、コンポーネントクラス自体があります。そして最後に、システムが必要とするコンポーネントを持つすべてのエンティティを取得する私のシステムがあります。 たとえば、私の移動システムは、位置コンポーネントと移動コンポーネントを持つすべてのエンティティを探します。位置コンポーネントは位置を保持し、移動コンポーネントは速度を保持します。 しかし、実際の問題は私の衝突システムです。このクラスは論理ブロブのようなものです。このクラスには特別なケースがたくさんあります。 例:パドルがボーダーと衝突する可能性があります。この場合、速度はゼロに設定されます。私のボールも国境にぶつかることがあります。しかし、この場合、その速度は境界線の法線でミラーリングされるだけなので、反映されます。これを行うために、私はボールに追加の物理コンポーネントを与えました。したがって、実際には、物理​​コンポーネントには実際のデータはありません。これは、オブジェクトが反射または停止したかどうかをシステムに通知するために存在する空のクラスです。 次に、これが発生します。ボールがパドルまたは境界に衝突したときに、いくつかのパーティクルをレンダリングしたいと思います。したがって、ボールは、衝突時にパーティクルを作成するように衝突システムに指示する別のコンポーネントを取得する必要があると思います。 次に、パドルと衝突するが境界とは衝突しないパワーアップが必要です。それが起こった場合、パワーアップは消えなければなりません。したがって、さらに多くのケースとコンポーネントが必要になります(一部のエンティティは特定のエンティティとのみ衝突できることをシステムに伝えるために、他の一部が実際に衝突できるとしても、すべてではなくボット、さらに衝突システムはパワーアップを適用する必要がありましたパドルなどなど)。 エンティティコンポーネントシステムは柔軟性があり、継承に問題がないので、良いことだと思います。しかし、私は現在完全に行き詰まっています。 複雑すぎると思いますか?この問題にどのように対処すればよいですか? もちろん、私は実際に「衝突後」の原因となるシステムを作成する必要があります。そのため、衝突システムは「はい、最後のフレームに衝突があります」とだけ表示し、次に「衝突後」システムがたくさんあります。すべて異なるコンポーネント(の組み合わせ)を必要とし、コンポーネントを変更します。たとえば、衝突が発生したときに停止する必要があるものを停止する衝突後移動システムがあります。次に、物事を反映する物理衝突後システムなど。 しかし、これは私にとっても適切な解決策ではないようです。たとえば、 私の移動後衝突システムには、位置コンポーネント、移動コンポーネント、および衝突コンポーネントを持つエンティティが必要です。次に、エンティティの速度をゼロに設定します。 物理衝突後システムには、位置コンポーネント、移動コンポーネント、衝突コンポーネント、および物理コンポーネントを持つエンティティが必要です。次に、速度ベクトルを反映します。 問題は明白です。衝突後の動きには、物理​​衝突後システムのエンティティのサブセットであるエンティティが必要です。したがって、2つの衝突後システムは同じデータで動作し、その効果は次のとおりです。エンティティには物理コンポーネントがありますが、衝突後の速度はゼロです。 これらの問題は、エンティティコンポーネントシステムで一般的にどのように解決されますか?それらの問題はいつものことですか?それとも私は何か間違っていますか?はいの場合、代わりに何をどのように行う必要がありますか?


2
コンポーネント間通信を安全かつキャッシュフレンドリーなコンポーネントストレージでサポートするにはどうすればよいですか?
コンポーネントベースのゲームオブジェクトを使用するゲームを作成していますが、各コンポーネントがゲームオブジェクトと通信する方法を実装するのに苦労しています。すべてを一度に説明するのではなく、関連するサンプルコードの各部分について説明します。 class GameObjectManager { public: //Updates all the game objects void update(Time dt); //Sends a message to all game objects void sendMessage(Message m); private: //Vector of all the game objects std::vector<GameObject> gameObjects; //vectors of the different types of components std::vector<InputComponent> input; std::vector<PhysicsComponent> ai; ... std::vector<RenderComponent> render; } GameObjectManagerすべてのゲームオブジェクトとそのコンポーネントを保持しています。また、ゲームオブジェクトの更新も行います。これは、コンポーネントベクトルを特定の順序で更新することによって行われます。配列の代わりにベクトルを使用するので、一度に存在できるゲームオブジェクトの数に実質的に制限はありません。 class GameObject …

1
コンポーネント/エンティティベースの設計+ビヘイビアツリー=>統合方法
私の現在のプロジェクトでは、コンポーネント/エンティティベースのシステムを実装しました。基本的に、このかなり未定義の領域にあるベストプラクティスのほとんどに従っています。 だから私は(少し拡張された)エンティティを取得しました。これは基本的にintID、人間が読める名前、std::mapコンポーネントのa 、およびlong存在するコンポーネントを示すために使用される「タイプインジケーター」です(私はenumすべてのコンポーネントに対して2の累乗を持っています)タイプと、コンポーネントがエンティティに追加されるときはいつでも、ビット単位の演算によってその長さを自動的に変更し、比較しますます。この回答を)。 次に、Componentsもあります。これもかなり単純です。コンポーネントタイプとしてのintID enum、親エンティティポインター、およびstd::mapこのコンポーネントが保持するすべてのプロパティのa です。 最後に、実際のロジック処理を処理するいくつかのシステム/マネージャー。彼らは最初に、現在処理されているエンティティに一致するlong「タイプインジケーター」があるかどうかをチェックします=そのシステムに必要なすべてのコンポーネントが存在します。次に、必要に応じていくつかのプロパティにアクセスし、それぞれのコンポーネントの関数を直接呼び出すか、メッセージディスパッチャを介してメッセージを送信します。 結論:ここまでは、かなり標準的なイベント駆動型のコンポーネント/エンティティベースのシステムとデータ駆動型のアプローチを組み合わせたものです(比較すると、コンポーネントにはハードコードされたデータ変数がなく、(一部の)コンポーネントとして一般的なマップがありますコンポーネントの/ archetypesは後で、実際のコンポーネントコードの一部ではない追加データを追加するオプションを使用してファイルから読み取られます。 次に、そのプロジェクトに(AiGameDev BTSKに基づく)動作ツリーも導入したいと思いますが、それらを既存のコンポーネントにリンクする必要があるかどうか、どのようにリンクするべきか、またはそれらのデザインを一般的に統合する方法はわかりません。 いくつかの関連するアイデア/ポイント/質問が頭に浮かびます: 私のBTはファイルから(再び)読み込まれます。現在BT Action、ツリー内のとアプリケーションの実際のコーディングとの間の接続を最適にする方法を確認するのに苦労しています。BTファイルで使用されるアクション名と実際のロジック実装への関数ポインターとの間に何らかのマップを作成する必要がありますか?それを解決するための通常のアプローチは何ですか? 私はすべての異なるEntityタイプ(つまり、ゲームロジックとAIに関連するコンポーネントの組み合わせのそれぞれについて、何度も言及した長い「タイプインジケーター」で示されるように)に対してBTを作成する必要があると思います。結果として、BT Actionアクションごとに多くのコンポーネントが関与する可能性が最も高いため、コンポーネントに実装を配置することは意味がありませんか? それで、BT Actionロジックは複数の個別のシステムに配置する必要がありますか(アイデア#1からのマップが指し示すメソッドに)。次に、システムは私のlong「タイプインジケーター」ごとにEntity、BTが現在チェックされており、特定のアクション(=システム内のメソッド)の実行が実際に許可されている(=必要なコンポーネントがある)かどうかをチェックします。しかし、そうでない場合(たとえば、BT作成者が特定の状況を見落とし、実行時に必要なコンポーネントがエンティティにアタッチされなくなる可能性があるため)、何も起こりません。 質問: そのような統合のための実証済みの概念はありますか? 上記の3つの点についてどう思いますか? コンポーネント/エンティティベースのデザイン全般に関して、他に思い浮かぶことはありますか?

2
エンティティシステムの多くの動きの原因
私はエンティティシステムのアイデアにかなり慣れていません。たくさんのものを読んだことがあります(最も便利なのは、この素晴らしいブログとこの回答)。 未定義の数のソースによってオブジェクトの位置を操作できるほど単純なものを理解するのに少し問題があります。 つまり、私にはエンティティがあり、これには位置コンポーネントがあります。次に、このエンティティに、指定された時間内に指定された距離を移動するように指示するイベントをゲームで実行します。 これらのイベントはいつでも発生する可能性があり、位置と時間の値は異なります。その結果、それらは一緒に合成されます。 従来のOOソリューションでMoveByは、距離/時間を含むある種のクラスと、ゲームオブジェクトクラス内のそれらの配列がありました。各フレームではMoveBy、すべてのを反復処理して、位置に適用します。がMoveBy終了時間に達した場合は、アレイから削除します。 エンティティシステムでは、この種の動作をどのように再現するべきかについて少し混乱しています。 一度にこれらの1つだけがあった場合、それらを一緒に合成することができる代わりに、それはかなり単純で(私は信じます)、次のようになります。 PositionComponent 含む x, y MoveByComponent 含む x, y, time Entitya PositionComponentとaの両方があるMoveByComponent MoveBySystemこれらのコンポーネントの両方を持つエンティティを探し、の値をMoveByComponentに追加しますPositionComponent。にtime到達すると、そのエンティティからコンポーネントが削除されます。 多くの移動方法で同じことをどのように行うかについて、私は少し混乱しています。 私の最初の考えは、私が持っているだろうということです: PositionComponent、MoveByComponent上記と同じ MoveByCollectionComponentMoveByComponentsの配列が含まれています MoveByCollectionSystemこれは、a PositionComponentとa を持つエンティティを探し、その内部MoveByCollectionComponentのMoveByComponentsを繰り返し、必要に応じて適用/削除します。 これはより一般的な問題だと思います。同じコンポーネントの多くがあり、それぞれに対応するシステムが動作することを望んでいるからです。私のエンティティには、コンポーネントタイプ->コンポーネントのハッシュ内にコンポーネントが含まれているため、エンティティごとに特定のタイプのコンポーネントが1つだけ存在します。 これはこれを見るのに正しい方法ですか? エンティティは常に特定のタイプのコンポーネントを1つだけ持つ必要がありますか?

3
エンティティコンポーネントシステムベースのエンジン
注:これはJavaScriptでプログラミングしていますが、ほとんどの場合、言語に依存しないはずです。 エンジンをECSベースのエンジンに変換することを考えています。 私は基本的なアイデアを得ます(注:これは間違っています、私の答えを参照してください): エンティティはゲームオブジェクトです。 コンポーネントは、エンティティに「接着」できる機能(reactToInput())または状態(position)のビットです。 システムには、管理および更新するエンティティのリストがあります。 しかし、私は実装といくつかの詳細を取得することを完全に確信していません... 質問:システムはさまざまな種類のエンティティで動作できますか?私は通常Scene、エンジンで呼び出されるクラスの例を示しますが、これもこの目的に役立ちます。シーンは、レンダリング、更新、レンダリング(ライト)に影響を与える可能性のあるすべてのオブジェクトのコンテナであり、将来的には2DSoundEmitterオブジェクトも含まれる可能性があります。それは高レベルのインターフェースを持っているので、ユーザーは自分が使用しているオブジェクトのタイプscene.add()や、そのようなすべてのものについて心配する必要はありません。 私はそれがSceneシステムかもしれないことを理解しています。エンティティを取り込んで格納し、更新メソッドを呼び出して、状態を変更することもできます。しかし、問題があります。上で説明したように、にはさまざまなタイプのオブジェクトをScene供給することができます。たとえば、シーンにレンダリング可能なオブジェクト(「ドローアブル」)とライトの両方が含まれている状況ではどうすればよいですか?相互作用する前にエンティティを型チェックする必要がありますか?または、さらに低いレベルで解決する必要があります。任意のオブジェクトに追加できるコンポーネントを作成すれば、ライトはとコンポーネントを持つエンティティになります。それは受け入れられますか?LightSourceLightSourcePosition また、従来の継承と従来のクラスを引き続き使用することは良い習慣ですか?たとえば、自分Rendererがどうなるかわからない!これはシステムではありません。唯一の機能は、カメラとシーンを取り込み、すべてをレンダリングして、エフェクト(シャドウなど)を適用することです。また、ゲームのコンテキスト、幅、高さを管理し、翻訳を行います...しかし、それはまだシステムではありません! 編集: ECSで見つけたリソースをリンクできますか?良いものを見つけるのに苦労しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.