FPSのエンティティシステムを設計しました。基本的には次のように機能します。
GameWorldと呼ばれる「世界」オブジェクトがあります。これは、GameManagerの配列とComponentManagerの配列を保持します。
GameObjectはComponentの配列を保持しています。また、非常にシンプルなイベントメカニズムも提供します。コンポーネント自体は、すべてのコンポーネントにブロードキャストされるイベントをエンティティに送信できます。
コンポーネントは基本的にGameObjectに特定のプロパティを与えるものであり、GameObjectは実際にはそれらの単なるコンテナであるため、ゲームオブジェクトに関係するすべてはコンポーネント内で発生します。例には、ViewComponent、PhysicsComponent、およびLogicComponentが含まれます。それらの間の通信が必要な場合は、イベントを使用して行うことができます。
ComponentManagerは、Componentと同様の単なるインターフェイスであり、各Componentクラスには、通常1つのComponentManagerクラスが必要です。これらのコンポーネントマネージャは、コンポーネントを作成し、XMLファイルなどから読み取ったプロパティでコンポーネントを初期化する役割を果たします。
ComponentManagerは、外部ライブラリを使用するPhysicsComponentのように、コンポーネントの大量更新も処理します(世界中のすべてを一度に実行します)。
構成可能性のために、XMLファイルまたはスクリプトのいずれかを読み取るエンティティのファクトリーを使用し、ファイルで指定されたコンポーネントを作成します(また、一括更新のために適切なコンポーネントマネージャーに参照を追加します)。次に、それらをGameObjectオブジェクトに注入します。
次に問題が発生します。これをマルチプレイヤーゲームに使用しようとしています。私はこれにどのようにアプローチするのか分かりません。
まず、最初からクライアントはどのエンティティを持っているべきですか?まず、シングルプレイヤーエンジンがどのエンティティを作成するかを決定する方法を説明する必要があります。
レベルエディタでは、「ブラシ」と「エンティティ」を作成できます。ブラシは、壁、床、天井など、基本的に単純な形状のものです。エンティティは、先ほどお伝えしたGameObjectです。レベルエディタでエンティティを作成するとき、各コンポーネントのプロパティを指定できます。これらのプロパティは、エンティティのスクリプト内のコンストラクターのようなものに直接渡されます。
ロードするエンジンのレベルを保存すると、エンティティとそれに関連付けられたプロパティのリストに分解されます。ブラシは「ワールドスポーン」エンティティに変換されます。
そのレベルをロードすると、すべてのエンティティがインスタンス化されます。簡単ですね。
さて、エンティティをネットワーク化するために、多くの問題に遭遇しました。最初に、最初からどのエンティティがクライアントに存在する必要がありますか?サーバーとクライアントの両方にレベルファイルがあると仮定すると、クライアントは、サーバー上のゲームルールのためだけに存在する場合でも、レベル内のすべてのエンティティをインスタンス化できます。
もう1つの可能性は、サーバーがその情報を送信するとすぐにクライアントがエンティティをインスタンス化することです。つまり、クライアントは必要なエンティティのみを持つことになります。
別の問題は、情報の送信方法です。サーバーはデルタ圧縮を使用できると思います。つまり、フレームごとにクライアントにスナップショットを送信するのではなく、何かが変更されたときにのみ新しい情報を送信します。ただし、サーバーは各クライアントが現時点で知っていることを追跡する必要があります。
最後に、ネットワークをエンジンにどのように注入する必要がありますか?ネットワーク化されることになっているすべてのエンティティに注入されるNetworkComponentというコンポーネントを考えています。しかし、どのようにネットワークコンポーネントの知っておくべきどのようなネットワークへの変数は、とどのようにそれらにアクセスするために、そして最終的にクライアントに対応するネットワークコンポーネントは、ネットワーク変数を変更する方法を知っている必要がありますか?
私はこれに近づくのに大きな問題を抱えています。あなたが途中で私を助けてくれたら本当に感謝しています。コンポーネントシステムの設計を改善するためのヒントも受け付けていますので、提案することを恐れないでください。