3

C# で記述されたサーバー ベースのマルチプレイヤー ゲームに取り組んでいます。サーバーとクライアントはコードを共有し、各オブジェクトには同じint ID. 変更されたデータのみを送信することで、ネットワークをできるだけ軽くしたいと考えています。

ゲームには多数のフィールド/プロパティを持つクラスがあり、それらは頻繁に変更されます。これらの値がいつ変化したかを検出し、これらの値をクライアント側に送信する方法を探しています。

基本的に、このアルゴリズム:

  1. オブジェクトが変更されたときにフラグを立てる
  2. ネットワーク Tick で変更されたオブジェクト:
    1. 各プロパティを以前の状態と比較する
    2. 変更された値のみを送信する
    3. 古い値を保存する
  3. クライアント側で受け取る
  4. 同じタイプのオブジェクトをインスタンス化するか、ID で検索します
  5. 新しい値を設定する

もちろん、.NET リフレクションはこの問題を解決できるかもしれませんが、各 Tick で 1000 個のオブジェクトとそのプロパティを反復処理すると、パフォーマンスのボトルネックになります。

基本型 (int、float、vector) を送信し、接続を維持できます。私の質問は次のとおりです。

オブジェクトを送信してClassインスタンス化するための最良の方法は何ですか?

プロパティの変更を検出する方法と、プロパティをシリアル化して、受信時にクライアントでそれらの「ペア」を見つける方法。

4

1 に答える 1

3

次のようなものを作成できます。

class Mob {
private int _health;
public int Health
{
   get { return _health; }
   set { _health = value; DirtyFlags |= MobDirtyFlags.Health
}
}

これは、各プロパティのコードが大量になることを意味します

または、カスタム ディクショナリを作成して、そのディクショナリのすべての変更を追跡することもできます。

mob.Properties["ヘルス"] = 10; あなたが何かを変更したことを追跡します。

これは、Mooege (Diablo 3 エミュレーター) がこれを行う方法です。

最初のアプローチは、アスペクトを使用して書き直すことができます (おそらく、Reflection.Emit または同様のものを介して実行時に上記で記述されたすべてのコードを生成するカスタム コード)。または、すべてのエンティティがどのように見えるかがわかっている場合は、いくつかのテンプレートからそれらのクラスを生成できます (T4 などを使用)。

シリアル化に関しては、これで十分です: (key: int, value: object) ここで、key は ActorProperties { Health, Strength, ...} のような列挙型になります。

于 2013-08-20T19:58:12.407 に答える