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

4
私のコードで「マネージャー」を避ける方法
この質問は、Software Engineering Stack Exchangeで回答できるため、Code Review Stack Exchangeから移行されました。 6年前に移行され ました。 現在、C ++向けにEntity Systemを再設計しています。多くのマネージャーがいます。私の設計では、ライブラリを結合するためにこれらのクラスがあります。「マネージャー」クラスに関しては、多くの悪いことを聞いたことがあります。おそらく、クラスに適切な名前を付けていません。しかし、他にどのような名前を付けるべきかはわかりません。 私のライブラリーのほとんどのマネージャーは、これらのクラスで構成されています(ただし、多少異なります)。 コンテナ-マネージャ内のオブジェクトのコンテナ 属性-マネージャー内のオブジェクトの属性 ライブラリの新しいデザインには、ライブラリを結び付けるために、これらの特定のクラスがあります。 ComponentManager-エンティティシステムのコンポーネントを管理します ComponentContainer コンポーネント属性 シーン*-シーンへの参照(以下を参照) SystemManager-エンティティシステム内のシステムを管理します SystemContainer シーン*-シーンへの参照(以下を参照) EntityManager-エンティティシステム内のエンティティを管理します EntityPool-エンティティのプール EntityAttributes-エンティティの属性(これはComponentContainerおよびSystemクラスのみがアクセス可能です) シーン*-シーンへの参照(以下を参照) シーン-すべてのマネージャーを結び付ける ComponentManager SystemManager EntityManager Sceneクラス自体にすべてのコンテナ/プールを配置することを考えていました。 すなわち これの代わりに: Scene scene; // create a Scene // NOTE: // I technically could wrap this line in …

5
エンティティコンポーネントシステムアーキテクチャは、定義上オブジェクト指向ですか?
エンティティコンポーネントシステムアーキテクチャは、定義上、オブジェクト指向ですか?それは私にとってより手続き的または機能的だと思われます。私の意見では、オブジェクト指向言語で実装することを妨げるものではありませんが、堅実なオブジェクト指向の方法で実装することは慣用的ではありません。 ECSはデータ(E&C)を動作(S)から分離しているようです。証拠として: アイデアは、エンティティにゲームメソッドを埋め込まないことです。 そして: コンポーネントは、特定の目的に必要な最小限のデータセットで構成されます。 システムは、特定のコンポーネントを持つエンティティのセットを使用する単一目的の機能です これはオブジェクト指向ではないと思います。オブジェクト指向になることの大部分は、データと振る舞いを組み合わせることだからです。 証拠として: 対照的に、オブジェクト指向のアプローチは、プログラムの残りの部分から直接アクセスできない場所にデータを配置することをプログラマに促します。代わりに、データにバンドルされている一般にメソッドと呼ばれる特別に記述された関数を呼び出すことにより、データにアクセスします。 一方、ECSは、行動からデータを分離することのすべてのようです。

2
エンティティーコンポーネントシステムは、デカップリング/情報隠蔽のためにひどいものではありませんか?
タイトルは意図的に双曲線であり、それは単にパターンに不慣れなだけかもしれませんが、ここに私の推論があります: エンティティを実装する「通常の」またはほぼ間違いなく簡単な方法は、それらをオブジェクトとして実装し、共通の動作をサブクラス化することです。古典的な問題へのこのリードは、「あるEvilTreeのサブクラスTreeかEnemy?」。多重継承を許可すると、ダイヤモンドの問題が発生します。私たちは、代わりの複合機能を引く可能性TreeとEnemy、さらにその神クラスへのリード線の階層までを、あるいは我々は意図的に私たちの中での行動を残すことができますTreeし、Entityそのことをクラス(彼らは極端なケースではインターフェースを作る)EvilTree自体ことを実装することができます-どのリードにコードの重複がある場合SomewhatEvilTree。 Entity-Component Systemsは、TreeおよびEnemyオブジェクトを異なるコンポーネント(たとえばPosition、Healthおよび)に分割してこの問題を解決し、AIの決定に従ってEntitiyの位置を変更するAIシステムなどを実装しようとしますAISystem。これまでのところは良いですがEvilTree、パワーアップを獲得してダメージを与えることができたらどうでしょうか?まず、a CollisionSystemとa が必要ですDamageSystem(おそらくこれらはすでにあるでしょう)。CollisionSystem通信するために必要なDamageSystem二つのものが衝突するたび:CollisionSystemにメッセージを送信しDamageSystem、それが健康を引くことができるようにします。ダメージもパワーアップの影響を受けるため、どこかに保存する必要があります。PowerupComponentエンティティにアタッチする新しいものを作成しますか?しかし、その後DamageSystemむしろ何も知らない何かについて知る必要があります-結局のところ、パワーアップを拾えないダメージを与えるものもあります(aなどSpike)。この回答と同様のダメージ計算にも使用されるPowerupSystemを修正するStatComponentことはできますか?しかし、現在では2つのシステムが同じデータにアクセスしています。ゲームがより複雑になると、多くのシステム間でコンポーネントが共有される無形の依存関係グラフになります。その時点で、グローバルな静的変数を使用して、すべての定型文を取り除くことができます。 これを解決する効果的な方法はありますか?私が持っていた1つのアイデアは、コンポーネントに特定の機能を持たせることでした。たとえばStatComponent attack()、デフォルトでは整数を返すだけですが、パワーアップが発生したときに構成できます: attack = getAttack compose powerupBy(20) compose powerdownBy(40) これはattack、複数のシステムがアクセスするコンポーネントに保存しなければならない問題を解決しませんが、少なくともそれを十分にサポートする言語があれば、関数を適切に入力できます。 // In StatComponent type Strength = PrePowerup | PostPowerup type Damage = Int type PrePowerup = Int type PostPowerup = Int attack: Strength = getAttack //default value, can be changed by systems getAttack: PrePowerup …

1
OOP ECSとPure ECS
まず、この質問はゲーム開発のトピックに関連していることを認識していますが、実際にはより一般的なソフトウェア生成問題に帰着するので、ここで質問することにしました。 過去1か月間に、Entity-Component-Systemsについてたくさん読んだので、今はその概念にとても慣れています。ただし、明確な「定義」が欠落しているように見える側面が1つあり、記事によって根本的に異なる解決策が提案されています。 これは、ECSがカプセル化を解除する必要があるかどうかの問題です。つまり、そのOOPスタイルのECS(コンポーネントは、それらに固有のデータをカプセル化する状態と動作の両方を持つオブジェクト)と純粋なECS(コンポーネントは、パブリックデータのみを持ち、システムが機能を提供するcスタイルの構造体)です。 フレームワーク/ API /エンジンを開発していることに注意してください。したがって、目標は、それを使用している人なら誰でも簡単に拡張できることです。これには、新しいタイプのレンダリングまたは衝突コンポーネントの追加などが含まれます。 OOPアプローチの問題 コンポーネントは他のコンポーネントのデータにアクセスする必要があります。たとえば、renderコンポーネントのdrawメソッドは、transformコンポーネントの位置にアクセスする必要があります。これにより、コードに依存関係が作成されます。 コンポーネントはポリモーフィックになる可能性があり、さらに複雑さをもたらします。たとえば、レンダーコンポーネントの仮想描画メソッドをオーバーライドするスプライトレンダーコンポーネントがある場合があります。 純粋なアプローチの問題 ポリモーフィックな動作(レンダリングなど)はどこかに実装する必要があるため、システムに外部委託するだけです。(たとえば、スプライトレンダーシステムは、レンダーノードを継承するスプライトレンダーノードを作成し、それをレンダーエンジンに追加します) システム間の通信は避けるのが難しい場合があります。たとえば、衝突システムには、そこにある具体的なレンダリングコンポーネントから計算される境界ボックスが必要な場合があります。これは、データを介して通信させることで解決できます。ただし、レンダリングシステムがバウンディングボックスコンポーネントを更新し、衝突システムがそれを使用するため、これによりインスタント更新が削除されます。システムの更新関数を呼び出す順序が定義されていないと、問題が発生する可能性があります。他のシステムがハンドラーをサブスクライブできるイベントをシステムが発生できるようにするイベントシステムがあります。ただし、これはシステムに何をすべきか、つまりvoid関数を伝える場合にのみ機能します。 追加のフラグが必要です。たとえば、タイルマップコンポーネントを見てみましょう。サイズ、タイルサイズ、インデックスリストフィールドがあります。タイルマップシステムは、それぞれの頂点配列を処理し、コンポーネントのデータに基づいてテクスチャ座標を割り当てます。ただし、フレームごとにタイルマップ全体を再計算するにはコストがかかります。したがって、システムでそれらを更新するために行われたすべての変更を追跡するために、リストが必要になります。OOPの方法では、これはタイルマップコンポーネントによってカプセル化できます。たとえば、SetTile()メソッドは、呼び出されるたびに頂点配列を更新します。 純粋なアプローチの美しさはわかりますが、従来のOOPよりも具体的にどのようなメリットがあるのか​​はよくわかりません。コンポーネント間の依存関係は、システムに隠されていますが、依然として存在しています。また、同じ目標を達成するには、さらに多くのクラスが必要になります。これは私には、決して良いことではない、やややりすぎたソリューションのように思えます。 さらに、私はパフォーマンスにそれほど関心がないので、データ指向の設計とキャッシュミスのこの全体的な考えは、私にはそれほど重要ではありません。素敵な建築物が欲しいだけです^^ それでも、私が読んだ記事や議論のほとんどは、2番目のアプローチを提案しています。どうして? アニメーション 最後に、純粋なECSでアニメーションをどのように処理するかについて質問したいと思います。現在、私はアニメーションを、0と1の間の進行状況に基づいてエンティティを操作するファンクタとして定義しています。アニメーションコンポーネントには、アニメーションのリストを持つアニメーターのリストがあります。次に、更新機能で、現在アクティブなアニメーションをエンティティに適用します。 注意: 私はこの投稿を読んだばかりですが、エンティティコンポーネントシステムアーキテクチャオブジェクトは定義によって指向されていますか?これは私よりも少し問題を説明します。基本的に同じトピックを扱っていますが、純粋なデータアプローチの方が優れている理由についてはまだ答えがありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.