ゲーム エンジンのエンティティ コンポーネント システムに取り組んでいます。私の目標の 1 つは、最適なデータ処理のためにデータ指向のアプローチを使用することです。言い換えれば、構造体の配列よりも配列の構造体が欲しいというガイドラインに従いたいのです。ただし、私の問題は、これを解決するためのきちんとした方法を見つけることができなかったことです。
これまでの私の考えでは、システム内のすべてのコンポーネントがゲームロジックの特定の部分を担当し、重力コンポーネントが質量、速度などに応じてフレームごとに力を計算し、他のコンポーネントが他のものを処理するとします。したがって、すべてのコンポーネントは異なるデータセットに関心があります。重力コンポーネントは質量と速度に関心があるかもしれませんが、衝突コンポーネントはバウンディング ボックスと位置などに関心があるかもしれません。
これまでのところ、属性ごとに 1 つの配列を保存するデータ マネージャーを使用できると考えました。つまり、エンティティには、重量、位置、速度などの 1 つ以上があり、一意の ID を持つとします。データ マネージャーのデータは次のように表されます。ここで、すべての数字はエンティティ ID を表します。
weightarray -> [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,1,2,3]
このアプローチは、すべてのエンティティがそれぞれの属性を持っている場合にうまく機能します。ただし、エンティティ 0 と 2 のみがすべての木の属性を持ち、他のエンティティが移動しないタイプのエンティティである場合、それらには速度がなく、データは次のようになります。
weightarray -> [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,2] //either squash it like this
velocityarray -> [0 ,2 ] //or leave "empty gaps" to keep alignment
突然、それを反復するのは簡単ではありません。反復処理と速度の操作のみに関心のあるコンポーネントは、2 番目のアプローチで行った場合、何らかの方法で空のギャップをスキップする必要があります。配列を短くする最初のアプローチは、より複雑な状況ではうまく機能しません。3 つの属性すべてを持つ 1 つのエンティティ 0、重量と位置のみを持つ別のエンティティ 1、位置と速度のみを持つエンティティ 2 があるとします。最後に、重みだけを持つ最後のエンティティ 3 が 1 つあります。押しつぶされた配列は次のようになります。
weightarray -> [0,1,3]
positionarray -> [0,1,2]
velocityarray -> [0,2]
他のアプローチでは、次のようなギャップが残ります。
weightarray -> [0,1, ,3]
positionarray -> [0,1,2, ]
velocityarray -> [0, ,2, ]
これらの状況はどちらも、少数の属性しか持たないエンティティーのセットを反復することにのみ関心がある場合、反復するのは自明ではありません。特定のコンポーネント X は、たとえば位置と速度を持つエンティティの処理に関心があります。反復可能な配列ポインタを抽出して、このコンポーネントに計算を実行させるにはどうすればよいですか? 要素が隣り合っている配列を指定したいのですが、それは不可能に思えます。
私は、すべての配列にビットフィールドを用意し、どのスポットが有効で、どのスポットがギャップであるかを記述する、または穴のない一時的な配列にデータをコピーしてからコンポーネントに与えるシステムなどのソリューションについて考えてきました。アイデアはありましたが、私が考えたものはエレガントではなく、処理のための追加のオーバーヘッドがありませんでした (データが有効かどうかの追加のチェック、またはデータの追加のコピーなど)。
誰かが似たような経験をしたり、この問題を追求するのに役立つアイデアや考えを持っていることを願っているので、ここで質問しています. :) また、このアイデア全体がくだらないものであり、正しく理解することが不可能であり、代わりにもっと良いアイデアがある場合は、教えてください. 質問が長すぎたり、雑然としたりしないことを願っています。
ありがとう。