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

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

4
ネットワークゲームで堅牢な方法でエンティティIDを割り当てるにはどうすればよいですか?
ネットワークゲームのエンティティシステムに取り組んでおり、各エンティティに一意の32ビット整数IDを割り当てています。このIDを使用して、エンティティおよびエンティティ自体への参照をシリアル化できます。 現在、エンティティが作成されるたびにカウンターをインクリメントしています。IDが最終的に使い果たされると思いますが、40億のエンティティがあるとは本当に思っていません。また、これにより、エンティティ#5が破棄され、IDが5になった場合に問題が回避されます。新しい#5を参照するのか、古い#5を参照するのですか? 問題は、衝突の処理/回避方法がわからないことです。現在、クライアントが現在の「フリーID」よりも高いIDを持つエンティティの更新を受け取ると、それまでのフリーIDにぶつかります。しかし、それはあまり堅牢ではないようです。 競合することなくエンティティを割り当てることができるように各クライアントに範囲を割り当てることを考えました(上位nビットはプレーヤー番号です)が、範囲が時間とともに重複し始めた場合にどうなるか心配です。 これを処理するより良い方法はありますか?idがオーバーフローしたり、許可された範囲の終わりを超えたりすることさえ気にする必要がありますか?これらのケースを検出するコードを追加できますが、クラッシュ以外の事態が発生した場合はどうなりますか。 もう1つのオプションは、128ビットGUIDのように一意である可能性が高いものを使用することですが、ネットワークトラフィックを最小限に抑えようとしているゲームにとっては非常に重いようです。また、現実的には、32ビットまたは24ビットの整数に収まるエンティティが一度に必要になることはありません。 ありがとう!

2
コンポーネントベースのエンティティシステムでのゲームの状態と入力の処理
私の質問は: ゲーム状態オブジェクトのスタックを保持することなく、エンティティシステムでゲーム状態を処理するにはどうすればよいですか? したがって、エンティティシステムの設計とは、たとえばエンティティが入力イベントに登録する必要がある場合、入力コンポーネントが入力システムを呼び出し、「このエンティティをこの入力に登録する」と言うことです。これはすべて問題ありませんが、これにゲーム状態の概念(たとえば、一時停止画面)を追加すると、エンティティが現在の状態にあり、入力を受け取る必要がある場合に解決することが問題になります。 「これらのゲーム状態にあるときにこのエンティティをこの入力に登録する」と言うように入力コンポーネント/システムを拡張できますが、これにはすべてのエンティティがどの状態で使用されるかを知る必要があり、それは明らかではないかもしれません。また、登録された入力(およびコールバックを使用する他のシステム)ごとにゲームの状態のリストを保持することは、あまり効率的ではありません。 私が持っていた別のアイデアは、ゲーム状態を表すエンティティがあり、無効になっていることをマークし、入力イベントを生成するときに、そのエンティティが無効なゲーム状態エンティティの子孫ではないことを確認することです。コールバックごとに親を解決するのは費用がかかるようです。 別のアイデアは、すべてのシステムに現在の状態に対してキー設定されたデータを保存させることです。そうすることで、入力を生成するときに、ターゲットエンティティは候補にさえなりません。しかし、これは異なる状態のエンティティ間の通信を許可する機能を本当に損ないます(一時停止画面ではそれほど問題ではありませんが、Oblivion / Skyrimでのロック選択を考えてください)。 私が持っていた唯一の他のアイデアは、すべてのコンポーネントが状態変更イベントを処理し、関連するシステムと通信して登録済みのものを無効にし、この状態に戻るときに再び有効にすることです。 2番目(オブジェクトを無効としてマークする)と4番目(各コンポーネントが状態の変更を処理する)は、私のアイデアの中で最高のように見えますが、特に素晴らしいと思うものはありません。 他の誰かがこれを行う方法について他のアイデアを持っていますか? 編集この質問では特に入力について説明しますが、衝突、タイマーイベントなど、エンティティにメッセージ/イベントを送信できるシステムを意味します。

3
エンティティとコンポーネントにメソッドを保存するのはなぜ悪い考えですか?(他のいくつかのエンティティシステムの質問と共に。)
これは私が答えたこの質問のフォローアップですが、これはより具体的なテーマに取り組んでいます。 この答えは、記事よりもエンティティシステムをよりよく理解するのに役立ちました。 エンティティシステムに関する(はい)記事を読みましたが、次のように伝えられました。 エンティティは単なるidとコンポーネントの配列です(記事では、コンポーネントにエンティティを保存することは物事を行う良い方法ではないと述べていますが、代替手段は提供していません)。 コンポーネントは、特定のエンティティで何ができるかを示すデータの断片です。 システムは「メソッド」であり、エンティティのデータの操作を実行します。 これは多くの状況で実際に実用的と思われますが、コンポーネントが単なるデータクラスであるという部分が気になります。たとえば、Entity SystemにVector2Dクラス(Position)を実装するにはどうすればよいですか? Vector2Dクラスはデータを保持します:x座標とy座標ですが、その有用性に重要なメソッドもあり、クラスを2つの要素配列から区別します。:例の方法がありadd()、rotate(point, r, angle)、substract()、normalize()、および他のすべての標準的な、便利な、と(Vector2Dクラスのインスタンスである)の位置が持つべきであることが絶対に必要なメソッド。 コンポーネントが単なるデータホルダーである場合、これらのメソッドを持つことはできません! おそらくポップアップする可能性のあるソリューションの1つは、システム内に実装することですが、それは非常に直感に反するようです。これらのメソッドは、私が今実行したいものであり、完全で使用可能な状態になっています。MovementSystemエンティティの位置の計算を実行するように指示する高価なメッセージセットを読み取るのを待ちたくありません! そして、記事は非常にはっきりと述べているだけのシステムが持つべきすべての機能を、私は見つけることができるそのための唯一の説明は、「OOPを避けるため」でした。まず第一に、エンティティやコンポーネントでメソッドを使用することを控えるべき理由がわかりません。メモリのオーバーヘッドは実質的に同じであり、システムと組み合わせた場合、これらは非常に簡単に実装し、興味深い方法で組み合わせる必要があります。たとえば、システムは、実装自体を知っているエンティティ/コンポーネントにのみ基本的なロジックを提供できます。あなたが私に尋ねると-これは基本的にESとOOPの両方から利点を取ります。これは記事の著者によるとできないことですが、私にとっては良い習慣のようです。 このように考えてください。ゲームにはさまざまな種類の描画可能なオブジェクトがあります。昔ながらの画像、アニメーション(update()、getCurrentFrame()など)、これらのプリミティブ型の組み合わせ、およびそれらのすべては、単純に提供できるdraw()だけで、その後、エンティティのスプライトがどのように実装されるかを気にする必要はありませんレンダリングシステムに方法をインターフェース(描画)と位置について。そして、レンダリングとは関係のないアニメーション固有のメソッドを呼び出すアニメーションシステムのみが必要になります。 そして、もう1つだけ...コンポーネントの保存に関して、配列の代替物は本当にありますか?Entityクラス内の配列以外にコンポーネントを保存する場所は他にありません... たぶん、これはより良いアプローチです:コンポーネントをエンティティの単純なプロパティとして保存します。たとえば、位置コンポーネントはに接着されentity.positionます。 他の唯一の方法は、異なるエンティティを参照する、システム内にある種の奇妙なルックアップテーブルを持つことです。しかし、それは非常に非効率的で、単にコンポーネントをエンティティに格納するよりも開発が複雑に思えます。

1
エンティティコンポーネントシステムのゲームエンジンでCPUキャッシュを活用するにはどうすればよいですか?
CPUキャッシュを賢く使用するための優れたアーキテクチャであるECSゲームエンジンのドキュメントをよく読みます。 しかし、CPUキャッシュの利点を理解することはできません。 コンポーネントが連続したメモリの配列(またはプール)に保存されている場合、コンポーネントを順番に読み取る場合にのみCPUキャッシュを使用するのが良い方法です。 システムを使用する場合、特定のタイプのコンポーネントを持つエンティティのリストであるエンティティリストが必要です。 ただし、これらのリストは、順番ではなくランダムな方法でコンポーネントを提供します。 それでは、キャッシュヒットを最大化するECSを設計する方法は? 編集: たとえば、物理システムには、RigidBodyおよびTransformコンポーネントを持つエンティティのエンティティリストが必要です(RigidBodyのプールとTransformコンポーネントのプールがあります)。 したがって、エンティティを更新するためのループは次のようになります。 for (Entity eid in entitiesList) { // Get rigid body component RigidBody *rigidBody = entityManager.getComponentFromEntity<RigidBody>(eid); // Get transform component Transform *transform = entityManager.getComponentFromEntity<Transform>(eid); // Do something with rigid body and transform component } 問題は、entity1のRigidBodyコンポーネントがそのプールのインデックス2にあり、entity1のTranformコンポーネントがそのプールのインデックス0にあることです(一部のエンティティは他のコンポーネントを持たず、エンティティを追加/削除するため/ランダムにコンポーネント)。 コンポーネントがメモリ内で連続している場合でも、それらはランダムに読み取られるため、キャッシュミスが多くなります。 ループ内の次のコンポーネントをプリフェッチする方法がない限り?

3
構成が重いOOP対純粋なエンティティコンポーネントシステム?[閉まっている]
現在のところ、この質問はQ&A形式には適していません。回答は事実、参考文献、または専門知識によってサポートされると予想されますが、この質問は議論、議論、世論調査、または広範な議論を求める可能性があります。この質問を改善し、場合によっては再開できると思われる場合は、ヘルプセンターをご覧ください。 7年前に閉鎖されました。 私は認めます、私は相続財産を濫用し、さらには虐待の罪を犯しました。OOPコースを受講するときに作成した最初の(テキスト)ゲームプロジェクトは、「ドア」と「1つのドアがある部屋」、「2つのドアがある部屋」から「ロックされたドア」と「ロック解除されたドア」 「部屋」から。 私が最近取り組んだ(グラフィカルな)ゲームでは、自分のレッスンを学び、継承の使用に制限をかけたと思いました。しかし、問題がすぐに現れ始めたことに気付きました。私のルートクラスはどんどん肥大化し始め、リーフクラスは重複したコードでいっぱいになりました。 私はまだ間違ったことをしていると思っていたので、オンラインで調べたところ、この問題を抱えているのは自分だけではないことがわかりました。いくつかの徹底的な調査の後、エンティティシステムを発見することになりました(読む:googlefu) 読み始めたとき、コンポーネントを使用した従来のOOP階層で発生していた問題をどれだけ明確に解決できるかを知ることができました。ただし、これらは最初の測定値でした。もっとつまずいたとき… T-machineのような「ラジカルな」ESアプローチ。 私は彼らが使っていた方法に反対し始めました。純粋なコンポーネントシステムは過剰であるか、直感的ではなく、おそらくOOPの強さのように見えました。著者は、ESシステムはOOPの反対であると言っており、OOPに沿って使用できるかもしれませんが、実際には使用すべきではありません。私はそれが間違っていると言っているわけではありませんが、実装したい解決策のような気がしませんでした。 ですから、私にとって、そして私の直感に反することなく、投稿の冒頭で抱えていた問題を解決するには、まだ階層を使用することですが、以前に使用したようなモノリシックな階層ではなく、ポリリシックなもの(モノリシックの反対語が見つかりませんでした)は、いくつかの小さな木で構成されています。 次の例は、私が何を意味するかを示しています(これは、Game Engine Architectureの第14章で見つけた例から着想を得ています)。 車両用の小さなツリーがあります。ルート車両クラスには、レンダリングコンポーネント、衝突コンポーネント、位置コンポーネントなどが含まれます。 そして、車両のサブクラスであるタンクは、そこからこれらのコンポーネントを継承し、独自の「キャノン」コンポーネントが与えられます。 キャラクターについても同じことが言えます。キャラクターは独自のコンポーネントを持ち、プレイヤークラスはそれを継承し、入力コントローラーを与えられますが、他の敵クラスはキャラクタークラスを継承し、AIコントローラーを与えられます。 この設計には問題はありません。純粋なEntity Controller Systemを使用していないにもかかわらず、バブリングアップ効果と大きなルートクラスの問題はマルチツリー階層を使用することで解決され、葉が重複しないため、葉を複製する重いコードの問題はなくなりました開始するコードは、コンポーネントだけです。リーフレベルに変更を加える必要がある場合、コードをどこにでもコピーペーストするのではなく、単一のコンポーネントを変更するのと同じくらい簡単です。 もちろん、私と同じように経験が浅いので、最初に単一階層の継承の重いモデルを使用し始めたときに問題は見られなかったため、現在実装を考えているモデルに問題がある場合は、それを見ることができます。 あなたの意見は? PS:私はJavaを使用しているため、通常のコンポーネントを使用する代わりに、多重継承を使用してこれを実装することはできません。 PPS:コンポーネント間の通信は、依存コンポーネントを相互にリンクすることにより行われます。これは結合につながりますが、私はそれが良いトレードオフだと思います。

3
外部コンポーネントマネージャーでエンティティシステムを整理しますか?
トップダウンマルチプレイヤー2Dシューティングゲーム用のゲームエンジンを設計しています。これは、他のトップダウンシューティングゲームで合理的に再利用できるようにしたいものです。現時点では、その中のエンティティシステムのようなものをどのように設計すべきかを考えています。最初に私はこれについて考えました: EntityManagerというクラスがあります。UpdateというメソッドとDrawという別のメソッドを実装する必要があります。ロジックとレンダリングを分離する理由は、スタンドアロンサーバーを実行している場合、Drawメソッドを省略できるためです。 EntityManagerは、BaseEntityタイプのオブジェクトのリストを所有しています。各エンティティは、EntityModel(エンティティの描画可能な表現)、EntityNetworkInterface、EntityPhysicalBodyなどのコンポーネントのリストを所有しています。 EntityManagerは、EntityRenderManager、EntityNetworkManager、EntityPhysicsManagerなどのコンポーネントマネージャーのリストも所有しています。各コンポーネントマネージャーは、エンティティコンポーネントへの参照を保持します。このコードをエンティティ自身のクラスから移動し、代わりにまとめて実行する理由はさまざまです。たとえば、ゲームには外部の物理ライブラリ、Box2Dを使用しています。Box2Dでは、最初にボディとシェイプをワールド(この場合はEntityPhysicsManagerが所有)に追加し、コリジョンコールバック(システムのエンティティオブジェクト自体にディスパッチされる)を追加します。次に、システム内のすべてをシミュレートする関数を実行します。このような外部コンポーネントマネージャーで行うよりも、これを行うための優れたソリューションを見つけるのは難しいと思います。 エンティティの作成は、次のように行われます。EntityManagerが登録方法のRegisterEntity(entityClass、工場)を実装する方法を、そのクラスのエンティティを作成することを。また、BaseEntity型のオブジェクトを返すメソッドCreateEntity(entityClass)も実装します。 ここで私の問題が起こります:コンポーネントへの参照はどのようにコンポーネントマネージャーに登録されますか?ファクトリー/クロージャーからコンポーネントマネージャーをどのように参照するかわかりません。

1
エンティティ/コンポーネントシステムでマテリアルを処理する方法
私のE / C実装は、エンティティが単なるIDであり、コンポーネントがデータであり、システムがデータに基づいて動作する基本的な実装です。現在、私はオブジェクトのマテリアルとレンダリング全般に問題を抱えています。単純なオブジェクトの場合、ModelComponentに関連付けられているRenderSystemにModelComponentは、レンダリングシステムが使用する頂点バッファーIDがあります。シンプルMaterialComponentはおそらく色や鏡面強度などを持っているでしょうが、複数のレンダーパスとの単純な変数ほど簡単ではない一般的な「効果」を可能にするのに十分な柔軟性が必要でしたMaterialComponent。 これらの問題を解決しようとして、2つの解決策を思いつきました。 1-超汎用材料コンポーネント このようなもの: struct Material : public Component { ShaderData* shader; std::vector<std::pair<std::string, boost::any>> uniforms; [...] }; レンダリングシステムでは、ユニフォームをループしてシェーダーに渡します。これは遅いと思いますが、私の目的には十分な速さです。 2-別の抽象化レイヤー、MaterialData 特定のマテリアルをラップするクラスを持ち、それは特殊なマテリアルに継承できますが、基本クラスは次のようなものになりますvoid set_shader_constants(ShaderData* d)が、実装は各クラスにMaterialComponent依存し、MaterialDataオブジェクトへのポインターを持ちます。 私がどちらのアプローチを好むかはわかりませんが、これらはどちらも複数のパスや他の複雑なレンダリング技術の主題には触れません。 これを達成する方法についてのアイデアはありますか?

2
エンティティシステムでの衝突の検出と応答
ESでもっと楽しく... 現在、私はいくつかのシステムを持っています: レンダラー(レンダリング可能属性、変換属性) モーション(移動可能な属性、変換属性、レンダリング可能な属性[境界ボックスなど]) 入力(InputReceiver属性) 等 衝突検出を追加しています。最初に考えたのは、衝突を実行する新しいシステムを追加することでした。これは、から分離され、これを維持するために私には理にかなってMotionカメラ等、霧、 - -移動またはが必ずしもアニメーション化されていることではないすべてのものは、衝突検出に関与するのでシステムが、と思われるCollisionとはMotion相互に依存しています。 Motionエンティティを移動する場合、変換はで検証する必要がCollisionあり、移動はキャンセルまたは調整(バウンス、壁での停止など)する必要があります。 別の方法として、衝突オブジェクトへの参照を保持するCollidable属性を作成する方法があります-kd-tree、octreeなどは、互いに衝突する可能性のあるエンティティ間で共有されます。Motionシステムは、その属性をチェックし、確認したり、動きを調整するためにそれを使用します。 コードの観点から見ると、これは許容できる解決策です。ただし、ECSアーキテクチャの観点からMotionは、Movable属性を持つすべてのエンティティに適用されないロジックをシステムにプッシュしているようです。 私はまた、動きベクトルを格納することができMovable、属性、および持っているColliderシステムは調整しTransform、必要に応じて、それは間の機能の重複を伴うだろうMotionとCollider、またはからのコールバックColliderへのMotionバウンス/反射などのための衝突場所と表面データに関するいくつかのデータを持ちます。 これは「特別なケースハック」という見出しに該当する可能性がありますが、大量のエッジケースコードを作成せずにこれを処理したことがある人から入力を受け取りたいと思います。 質問 モーションシステムと衝突システムがお互いの知識を必要とするように思われる場合、それらのシステム間の密結合を回避する良い方法は何ですか?

2
Entity System Frameworkのタイルマップ?
私はEntity System Frameworks、特にArtemisについて読んでいます。私に合っているかどうかを判断しようとしています。私はタイルベースの2Dピクセルアートゲームに厳密に取り組んでいますが、これほどリソース集約型になるとは思いません。過去に多くの継承を伴う標準OOPを常に使用していました。 Entity System Frameworkの現在の理解(まだ完全に把握しているかどうかはわかりません): エンティティはIDに他なりません コンポーネントは、エンティティコンポーネントプールに追加されるダムデータにすぎません システムは、システムコンポーネントシグネチャに一致するすべてのエンティティを処理するために、世界に接続される更新機能です 私の理解が正しければ、このフレームワークにタイルマップとAIビヘイビアツリーを追加する概念化にかなり苦労しています。今後AIについてお聞きします。 このフレームワークにタイルマップを組み込む必要がありますか?または、タイルマップエディターで簡単に生成できるように、個別に保持する必要がありますか? タイルマップをこのフレームワークに組み込む必要がある場合、各タイルは異なるエンティティですか?タイルマップはシステムですか?それとも、タイルマップ自体は、それから構築された継承を持つ単一のエンティティですか? タイルマップが独立している場合、外部タイルマップに対してエンティティを衝突検出する最良の方法は何でしょうか? 私がリストした複数のオプションが正しいかもしれないことを理解していますが、誰かが過去にこれをやったことがあるなら、彼らは私の混乱にいくらかの光を当てることができるかもしれません。たぶん私が考えていない別の選択肢がありますか? ありがとうございました。

3
コンポーネントベースの設計における入力処理
この質問が何度も尋ねられたことは知っていますが、コンポーネントベースのエンジンで入力処理を実装する方法はまだわかりません。 私が使用したコンポーネントベースのデザインは、T = Machineのブログシリーズと、エンティティが単なるIDであるArtemisに基づいていました。 入力処理の実装には、主に3つのアイデアがあります。 入力コンポーネントは、関心のあるイベントを保持します。入力システムは、キーイベントとマウスイベントをゲームイベントに変換し、エンティティを入力コンポーネントとともにループします。イベントに関心がある場合は、入力システムによって適切なアクションが実行されます。このアクションは、入力システムにハードコーディングされます。 入力コンポーネントはありません。特定のイベントを持つエンティティを入力システムに登録します。次に、入力システムはメッセージ(エンティティIDとイベントタイプを含む)を他のシステムに送信し、これらが適切なアクションを実行できるようにします。または、最初のケースと同様に、アクションは入力システムにハードコーディングされます。 最初のメソッドと同様ですが、アクションを入力システムにハードコーディングする代わりに、コンポーネントにはstd::map<std::function>、入力システムによって呼び出される関数(つまり)へのイベントのマップが含まれます。これには、同じイベントを異なるアクションに結合できるという追加の効果があります。 上記の方法のいずれかをお勧めしますか、それとも柔軟な入力処理システムを実装するのに役立つ提案がありますか?また、私はまだマルチスレッドに精通していませんが、実装をスレッドフレンドリーにする提案があれば歓迎します。 注:実装が満たしてほしい追加の要件の1つは、たとえばカメラエンティティとプレーヤーを同時に移動するなど、同じ入力を多くのエンティティに渡すことができることです。

1
エンティティコンポーネントシステム-オブジェクトの変換を実装する方法
エンジンのエンティティコンポーネントシステムを設計する際に、特定のタイプのコンポーネントを格納および取得する方法に少し問題がありました。 最初に、この質問で使用する少しの用語を明確にします。 「コンポーネント」を、特定のシステムに関連するデータを格納するデータ構造と呼びます。 私は、「システム」をメソッドとデータ構造の集合体と呼び、コンポーネントを使用してユーザーとのゲームの状態/インターフェースを更新します。 「エンティティ」は基本的に、特定のコンポーネントを取得し、ゲームロジックでそれらのデータを変更するために使用される単なるIDです。 各システムは、コンポーネントのタイプ(例:Physics-> PhysicsComponent、AI-> AIComponent、Rendering-> RenderingComponent)の(IDマップ)配列を所有しているため、データを効率的に反復できます。 ただし、すべてのコンポーネントが特定のシステムによって所有されているわけではありません。たとえば、Transformコンポーネントはオブジェクトの位置、回転、スケールを保存します。物理学、AI、レンダリングなどの多くのシステムで使用されているため、エンティティの最も重要な部分の1つです(Unityは必須にします)。 これはほとんど私が直面している問題です。Transformは他の多くのシステムで使用されているので、コンポーネントごとに使用するものを取得するにはどうすればよいですか?考えられる解決策の1つは、各コンポーネントに独自のエンティティIDを格納させることです。このようなコンポーネントを取得するのは簡単ですが、それほど効率的ではありません。また、他のコンポーネントを認識していない、分離された独立したデータのバンドルとしてのコンポーネントの概念に反します。 この問題を解決する適切な方法はありますか?Transformもコンポーネントにする必要がありますか?

3
エンティティ/コンポーネントシステムでエンティティを同時に処理するための読み取り/計算/書き込みステップを効率的に分離
セットアップ エンティティコンポーネントアーキテクチャがあり、エンティティは一連の属性(動作のない純粋なデータ)を持つことができ、そのデータに作用するエンティティロジックを実行するシステムが存在します。基本的に、やや疑似コードで: Entity { id; map<id_type, Attribute> attributes; } System { update(); vector<Entity> entities; } すべてのエンティティに沿って一定の速度で移動するシステムは、 MovementSystem extends System { update() { for each entity in entities position = entity.attributes["position"]; position += vec3(1,1,1); } } 基本的に、私はupdate()をできるだけ効率的に並列化しようとしています。これは、システム全体を並行して実行するか、1つのシステムの各update()にいくつかのコンポーネントを与えることにより、異なるシステムが同じシステムの更新を実行できるようにして、そのシステムに登録されたエンティティの異なるサブセットに対して実行できます。 問題 示されているMovementSystemの場合、並列化は簡単です。エンティティは相互に依存せず、共有データを変更しないため、すべてのエンティティを並行して移動できます。 ただし、これらのシステムでは、エンティティが相互にやり取りする(データを読み書きする)ことが必要な場合があります。同じシステム内でも、相互に依存する異なるシステム間である場合がよくあります。 たとえば、物理システムでは、エンティティが互いに相互作用する場合があります。2つのオブジェクトが衝突し、それらの位置、速度、およびその他の属性がオブジェクトから読み取られて更新され、更新された属性が両方のエンティティに書き戻されます。 エンジンのレンダリングシステムがエンティティのレンダリングを開始する前に、他のシステムが実行を完了するのを待って、関連するすべての属性が必要な属性であることを確認する必要があります。 これを盲目的に並列化しようとすると、異なるシステムが同時にデータを読み取り、変更する可能性がある従来の競合状態が発生します。 理想的には、他のシステムが同じデータを同時に変更することを心配することなく、またプログラマが実行と並列化を適切に順序付けすることを気にすることなく、すべてのシステムが必要なエンティティからデータを読み取ることができるソリューションが存在しますこれらのシステムを手動で(場合によっては不可能になることもあります)。 基本的な実装では、これはすべてのデータの読み取りと書き込みをクリティカルセクションに配置するだけで実現できます(ミューテックスで保護します)。しかし、これは大量のランタイムオーバーヘッドを引き起こし、パフォーマンスに敏感なアプリケーションにはおそらく適していません。 解決? 私の考えでは、考えられる解決策は、データの読み取り/更新と書き込みが分離されているシステムであり、1つの高価なフェーズでは、システムはデータの読み取りと計算に必要なものだけを計算し、何らかの方法で結果をキャッシュしてからすべて書き込みます。別の書き込みパスで変更されたデータをターゲットエンティティに戻します。すべてのシステムは、フレームの先頭にある状態でデータに作用し、その後、フレームの終わりの前に、すべてのシステムが更新を完了すると、シリアル化された書き込みパスが発生し、すべての異なるキャッシュ結果がキャッシュされますシステムは反復され、ターゲットエンティティに書き戻されます。 これは、簡単な並列化の勝利が結果のキャッシュと書き込みパスのコスト(実行時のパフォーマンスとコードのオーバーヘッドの両方の点で)を上回るほど大きくなる可能性がある(多分間違っているか?)という考えに基づいています。 質問 最適なパフォーマンスを実現するために、このようなシステムをどのように実装するのでしょうか?そのようなシステムの実装の詳細と、このソリューションを使用するエンティティコンポーネントシステムの前提条件は何ですか?

2
コンポーネントベースのエンティティシステムでのスクリプト化された「ネイティブ」コンポーネントの処理
私は現在、コンポーネントベースのエンティティシステムを実装しようとしています。エンティティは基本的に単なるIDであり、いくつかのコンポーネントを束ねてゲームオブジェクトを形成するヘルパーメソッドです。そのいくつかの目標は次のとおりです。 コンポーネントには状態のみが含まれます(例:位置、ヘルス、弾薬数)=>ロジックは「システム」に入り、これらのコンポーネントとその状態(例:PhysicsSystem、RenderSystemなど)を処理します 純粋なC#とスクリプト(Lua)の両方でコンポーネントとシステムを実装したいと思います。基本的に、C#ソースを再コンパイルすることなく、完全に新しいコンポーネントとシステムをLuaで直接定義できるようにしたいと考えています。 これを効率的に一貫して処理する方法についてのアイデアを探しているので、たとえば、C#コンポーネントやLuaコンポーネントにアクセスするために別の構文を使用する必要はありません。 私の現在のアプローチは、通常のパブリックプロパティを使用してC#コンポーネントを実装することです。おそらく、エディターにデフォルト値などを伝えるいくつかの属性で装飾されています。次に、C#クラス "ScriptComponent"を作成します。これは、Luaテーブルを内部でラップするだけで、このテーブルはスクリプトによって作成され、特定のコンポーネントタイプのすべての状態を保持します。コンパイル時にはわからないので、C#側からはその状態にあまりアクセスしたくないのですが、どのScriptComponentsにどのプロパティを使用できるかはわかりません。それでも、エディターはそれにアクセスする必要がありますが、次のような単純なインターフェースで十分です。 public ScriptComponent : IComponent { public T GetProperty<T>(string propertyName) {..} public void SetProperty<T>(string propertyName, T value) {..} } これは単にLuaテーブルにアクセスし、Luaからこれらのプロパティを設定および取得するだけで、純粋なC#コンポーネントにも簡単に含めることができます(ただし、通常のC#プロパティをリフレクションなどで使用します)。これはエディターでのみ使用され、通常のゲームコードでは使用されないため、ここではパフォーマンスはそれほど重要ではありません。特定のコンポーネントタイプが実際に提供するプロパティを文書化したコンポーネントの説明を生成または手書きする必要がありますが、それは大きな問題ではなく、十分に自動化できます。 しかし、Lua側からコンポーネントにアクセスする方法は?たとえばgetComponentsFromEntity(ENTITY_ID)、「ScriptComponent」を含むネイティブのC#コンポーネントの束をユーザーデータとして取得することになるでしょう。ラップされたLuaテーブルから値GetProperty<T>(..)にアクセスすると、他のC#コンポーネントのようにプロパティに直接アクセスする代わりに、メソッドが呼び出されます。 おそらくgetComponentsFromEntity()、Luaからのみ呼び出される特別なメソッドを記述します。これは、代わりにラップされたテーブルを返す「ScriptComponent」を除いて、すべてのネイティブC#コンポーネントをユーザーデータとして返します。しかし、他のコンポーネント関連のメソッドがあるので、C#コードまたはLuaスクリプトから呼び出されるために、これらのメソッドをすべて複製したくありません。 最終的な目標は、ネイティブコンポーネントとLuaコンポーネントを区別する特別なケース構文なしで、特にLua側から、すべてのタイプのコンポーネントを同じように処理することです。たとえば、次のようなLuaスクリプトを記述できるようにしたいと思います。 entity = getEntity(1); nativeComponent = getComponent(entity, "SomeNativeComponent") scriptComponent = getComponent(entity, "SomeScriptComponent") nativeComponent.NativeProperty = 5 scriptComponent.ScriptedProperty = 3 スクリプトは、実際に取得したコンポーネントの種類を気にする必要はありません。C#側から使用するのと同じメソッドを使用して、コンポーネントを取得、追加、または削除します。 たぶん、そのようなエンティティシステムとスクリプトを統合するいくつかのサンプル実装がありますか?

5
エンティティ構成をスクリプトの外に配置するのはなぜですか?
スクリプトファイルでエンティティコンポーネントを定義する多くのゲームを見てきましたが、各エンティティを構成し、そのエンティティが持つコンポーネントを指定するとき、他のファイル形式(XMLなど)を使用します。なぜ彼らはそれをするのですか? 私は主に他の人の根拠がこれについて何であったかを確認するように求めています。私はまた、(私はXML JSONを選択しなかったが)外のスクリプトの私のエンティティを設定します。これを行う理由は、セーブゲームを簡単に実装できるようにするためです。また、この種の構成はXMLやJSONのようなものに整理するほうがよいと思うからです。 @ クリストファーラーセンの答え: コメントとして投稿するには長すぎる 質問の主題から少し逸脱しているのではないかと思います。あなたが説明している問題は、階層ベースのエンティティにより関連しています。私の質問では、コンポーネントベースのエンティティについて話していることを述べました。 これが私が聞きたかった例です。以下は、エンティティを構成する2つの代替方法です。スクリプトを使用する方法と外部JSONファイルを使用する方法です。私の質問は、なぜ多くの人がスクリプトの外でエンティティを構成することを好むのかということでした。 基本エンティティクラス: class Entity: def __init__(self, name): pass def addComponent(self, comp): pass スクリプトのアプローチ: orc = Entity('Orc') orc.addComponent(PositionComponent(3.4, 7.9)) JSONアプローチ: { "name" : "Orc", "components": { "PositionComponent": { "x" : 3.4, "y" : 7.9 } } } このアプローチを使用する理由は既に述べましたが、これは技術的で組織的なものです。なぜこれほど多くの他の人(私が見たものから)がこれを使用するのか知りたいと思いました。

4
Luaエンティティの作成/管理に優れたゲームエンジン[終了]
現在のところ、この質問はQ&A形式には適していません。回答は事実、参考文献、または専門知識によってサポートされると予想されますが、この質問は議論、議論、世論調査、または広範な議論を求める可能性があります。この質問を改善し、場合によっては再開できると思われる場合は、ヘルプセンターをご覧ください。 6年前に閉鎖されました。 Luaまたは他のスクリプト言語を使用してエンティティを構築するエンジンを探しています。これは、インスピレーションを見つけて自分のエンジンでも行うためです。 CryEngineはエンティティを作成するためにLuaを使用することを知っていますが、他に検索できる代替策があるかどうかを知りたいと思っていました。 ありがとう!

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