10

この質問またはそのバリエーションがたくさん出回っていると思うので、私が言っていることが重複していて、答えが他の場所にある場合は、お知らせください.

私はゲーム エンジンの設計を研究しており、コンポーネント ベースのエンティティ モデルに出会いました。有望に聞こえますが、私はまだその実装に取り​​組んでいます。

エンジンがいくつかの「サブシステム」で構成され、レンダリング、サウンド、ヘルス、AI などの側面を管理するシステムを検討しています。各サブシステムには、ヘルスのヘルス コンポーネントのようなコンポーネント タイプが関連付けられています。サブシステム。NPC、ドア、何らかの視覚効果、プレイヤーなどの「エンティティ」は、1 つまたは複数のコンポーネントで構成されており、それらを組み合わせることでエンティティにその機能を提供します。

情報伝達の 4 つの主なチャネルを特定しました。コンポーネントは現在のエンティティ内のすべてのコンポーネントにブロードキャストでき、コンポーネントはそのサブシステムにブロードキャストでき、サブシステムはそのコンポーネントにブロードキャストでき、サブシステムは他のサブシステムにブロードキャストできます。

たとえば、ユーザーがキャラクターを動かしたい場合は、キーを押します。このキーの押下は、入力サブシステムによって取得され、イベントがブロードキャストされ、プレーヤー サブシステムによって取得されます。次に、プレーヤー サブシステムは、このイベントをすべてのプレーヤー コンポーネント (およびそれらのコンポーネントが構成するエンティティ) に送信します。これらのプレーヤー コンポーネントは、独自のエンティティの位置コンポーネントと通信して先に進み、移動します。

キーを押すためのこれらすべては少し複雑に思えますが、私は確かにこのアーキテクチャの改善にオープンです。とにかく、私の主な質問はまだ続きます。

イベント自体については、訪問者パターンのようにイベントがどこで振る舞うかを考えました。私が望んでいることの重要性は、イベントがサポートしていないコンポーネントに遭遇した場合 (移動イベントは AI や健康とは直接関係がないため)、そのコンポーネントを無視することです。イベントが後を追っているコンポーネントを見つけられなくても、それは問題ではありません。

訪問者パターンはほぼ機能します。ただし、コンポーネントのすべてのタイプ (つまり、visitHealthComponent、visitPositionComponent など) に関係がない場合でも、仮想関数が必要になります。これらの関数を空のままにしておくこともできます (そのため、これらのコンポーネントに遭遇した場合は無視されます) が、コンポーネントを追加するたびに別の関数を追加する必要があります。

私の希望は、必ずしも他の場所に何かを追加することなくコンポーネントを追加し、他のものを台無しにすることなくイベントを追加できることでした.

だから、私の2つの質問:

  1. 効率や柔軟性などの点で、私の設計で可能な改善点はありますか?
  2. イベントを処理する最適な方法は何でしょうか?
4

4 に答える 4

1

ここで説明されているこのアーキテクチャhttp://members.cox.net/jplummer/Writings/Thesis_with_Appendix.pdf 実際のプロジェクトでこれを実装して遭遇した少なくとも 3 つの問題があります。

  1. システムは何かが起こったときに通知されません - 唯一の方法はそれについて尋ねることです - プレイヤーは死んでいますか? 壁が見えない?など - これを回避するには、オブザーバー パターンの代わりに単純な MVC を使用できます。
  2. オブジェクトが複合体 (つまり、オブジェクトで構成されている) の場合はどうなりますか? システムはすべての階層を走査し、コンポーネントの状態について尋ねます。
  3. そして、主な欠点は、このアーキテクチャがすべて混ざり合っていることです。たとえば、キーを押したことをプレーヤーが知る必要があるのはなぜですか?

その答えは、抽象化された表現を備えた階層化されたアーキテクチャだと思います...

于 2011-05-21T17:54:35.630 に答える
1

私は自分のプロジェクトの 1 つにエンティティ システムを使用することを考えていて、同様の思考プロセスを経てきました。私の最初の考えは、イベントを処理するためにオブザーバー パターンを使用することでした。

私の考えでは、サブシステムはサブシステム固有のパブリッシュ/サブスクライブ インターフェイスを提供するため、サブシステムの依存関係は「半疎」に結合された方法で解決されます。別のサブシステムからのイベントに依存するサブシステムは、そのサブシステムへのサブスクライバー インターフェイスを認識しているため、それを効果的に利用できます。

残念ながら、これらのサブスクライバーがパブリッシャーへのハンドルを取得する方法は、まだ頭の中にある問題です。この時点で、私は、各サブシステムがインスタンス化されるある種の動的な作成を支持しています。次に、第 2 フェーズを使用して依存関係を解決し、すべてのサブシステムを「準備完了状態」にします。

とにかく、私はあなたのために何がうまくいったか、そしてあなたのプロジェクトであなたが遭遇した問題に非常に興味があります:)

于 2010-10-28T22:25:40.677 に答える
1

イベントバス、別名イベントアグリゲーターを使用します。必要なのは、サブシステム間の結合を必要としないイベント メカニズムであり、イベント バスはまさにそれを行います。

http://martinfowler.com/eaaDev/EventAggregator.html http://stackoverflow.com/questions/2343980/event-aggregator-implementation-sample-best-practices

于 2010-12-21T09:39:07.227 に答える
1

下手な英語ですみません。

Entity-Component System に基づいた、柔軟でスケーラブルな Java 3D ゲーム エンジンを作成しています。私はそれのいくつかの基本的な部分を終えました。

最初に ECS アーキテクチャについて言いたいのですが、コンポーネントが同じエンティティ内の他のコンポーネントと通信できることに同意しません。コンポーネントはデータのみを保存し、システムはそれらを処理する必要があります。

イベントハンドリングの部分では、基本的な入力ハンドリングは ECS に含めるべきではないと思います。代わりに、Intent System というシステムと、多くのインテントを含む Intent Component というコンポーネントがあります。意図とは、エンティティがエンティティに対して何かをしたいという意味です。インテント システムはすべてのインテントを処理します。インテントを処理するとき、対応する情報を他のシステムにブロードキャストするか、エンティティに他のコンポーネントを追加します。

Intent Generator というインターフェイスも作成しています。ローカル ゲームではキーボード入力またはマウス入力ジェネレーターを実装でき、マルチプレイヤー ゲームではネットワーク インテント ジェネレーターを実装できます。AI システムでは、インテントを生成することもできます。

インテント システムがゲーム内で処理する処理が多すぎると思われるかもしれません。しかし実際には、多くの処理を他のシステムと共有しており、スクリプト システムも作成しています。特定の特別なエンティティには、特別なことを行うスクリプト コンポーネントがあります。

もともと何かを開発するときは、すべてを含めた素晴らしい建築を作りたいと常に思っています。しかし、ゲーム開発では非常に非効率な場合があります。異なるゲーム オブジェクトは、まったく異なる機能を持っている場合があります。ECS は、データ指向プログラミング システムとして優れています。しかし、完全なゲームにすべてを含めることはできません。

ちなみに、私たちの ECS ベースのゲーム エンジンは、近い将来オープン ソースになるので、それを読むことができます。興味のある方は、ぜひご参加ください。

于 2014-05-13T02:00:45.510 に答える