(私が説明しているのは、この設計に基づいています:エンティティシステムフレームワークとは何ですか?、下にスクロールすると見つかります)
C ++でエンティティコンポーネントシステムを作成するときに問題が発生します。コンポーネントクラスがあります。
class Component { /* ... */ };
これは実際には、他のコンポーネントを作成するためのインターフェースです。したがって、カスタムコンポーネントを作成するには、インターフェイスを実装し、ゲーム内で使用されるデータを追加するだけです。
class SampleComponent : public Component { int foo, float bar ... };
これらのコンポーネントはEntityクラス内に格納され、Entityの各インスタンスに一意のIDが付与されます。
class Entity {
int ID;
std::unordered_map<string, Component*> components;
string getName();
/* ... */
};
コンポーネントは、コンポーネントの名前をハッシュすることでエンティティに追加されます(これはおそらくそれほど素晴らしい考えではありません)。カスタムコンポーネントを追加すると、コンポーネントタイプ(ベースクラス)として保存されます。
一方、今では、内部にNodeインターフェースを使用するSystemインターフェースがあります。Nodeクラスは、単一のエンティティのコンポーネントの一部を格納するために使用されます(システムはエンティティのすべてのコンポーネントの使用に関心がないため)。システムがupdate()
必要な場合、システムは異なるエンティティから作成されたノードを反復処理するだけです。そう:
/* System and Node implementations: (not the interfaces!) */
class SampleSystem : public System {
std::list<SampleNode> nodes; //uses SampleNode, not Node
void update();
/* ... */
};
class SampleNode : public Node {
/* Here I define which components SampleNode (and SampleSystem) "needs" */
SampleComponent* sc;
PhysicsComponent* pc;
/* ... more components could go here */
};
問題は、エンティティをSampleSystemに渡すことでSampleNodesを構築するとしましょう。次に、SampleNodeは、エンティティにSampleSystemが使用する必要なコンポーネントがあるかどうかを「チェック」します。エンティティ内の目的のコンポーネントにアクセスする必要があるときに問題が発生します。コンポーネントはComponent
(基本クラス)コレクションに格納されているため、コンポーネントにアクセスして新しいノードにコピーできません。私は一時的にComponent
派生型にキャストすることで問題を解決しましたが、これを行うより良い方法があるかどうかを知りたかったのです。これがすでに持っているものを再設計することを意味するかどうかを理解しています。ありがとう。