2011-01-26 11 views
1

私は大量のゲームエンティティを扱う自分のゲームを作成しています(カウントは約1000です)。 すべてのエンティティを画面に描画する必要があります。最初は、C#が私に良いフレームレートを与えることは確かではありませんでした。しかし、基本的なカリングを適用したとき、私はさらに高いフレームレートにショックを受けました。オブジェクトの膨大な量を管理する

これでエンティティにAIロジックを追加すると、すべてのオブジェクトの更新時間に多少の時間がかかります。私はオブジェクトを持つリストを持っていて、それらをトラフループしてobj.Update(dt)を呼び出す。この方法が最善ではないように見えます。 「巨大な」エンティティの更新には多くの時間がかかりますので、他の人は更新が完了するまで待つ必要があります。

私の質問は:どのように動的オブジェクトの膨大な量を管理する方が良いですか?

+4

はマルチスレッド/パラレル処理オプションですか? – TDaver

+7

ゲーム開発のための専用ウェブサイトhttp://gamedev.stackexchange.com/には完璧なコンテンツと思われます。 –

+1

可能であれば、更新を並行して行うことを検討してください。 – jason

答えて

3

問題は、Updateメソッドを呼び出すオブジェクトをループしていることです。何かが更新されていない場合はどうなりますか?何かがなければ、はすべてのフレームで更新する必要があります

あなたのメインループにイベントを追加し、あなたのオブジェクトは、それに加入持つ方:何も更新する必要があるとき

public void FrameListener(float _ticks); 


public class Game 
{ 
    public Event FrameListener OnFrame; 
} 

、それだけで渡されたデルタティック・カウントを取得(このイベントをサブスクライブそれに)。オブジェクトがアイドル状態になると、オブジェクト自体の登録を解除できます。この方法を使用すると、にはの更新が必要なオブジェクトのみが更新されます。

また、サブスクリプションプロセスにカウンタを追加することもできます(つまり、イベントオブジェクトをAddListener()タイプのメソッドに置き換えることができます)。システムは、 'n'フレームごとにデリゲートを呼び出すようにシステムに指示します。たとえば、(定住者、文明などの)制作物を作っているかもしれないゲームでは、これらのものがすべてのフレームで制作物を更新することは意味がありません。 5秒ごとでさえ十分です。これにより、オブジェクトを更新する必要がある正確な頻度を定義できるときに、多くのオーバーヘッドが削減されます。

スタティックオブジェクトはデリゲートを植え付けることがないため、オーバーヘッドは発生しません。

3

まず、1000個のオブジェクトは実際には巨大なではありません。 60fpsでは、60kHzです。これは、オブジェクトごとに、ほとんどのハードウェアで16μs(少なくとも32,000クロック・サイクル)です。いくつかのオブジェクトは高いコストを負わなければなりません。

オブジェクトごとのコストを下げることはできないと仮定して、オブジェクトの更新に合計時間予算を割り当て、その時間が経過するとループを停止しますが、次のフレームの同じ場所からループを繰り返し、あなたが終わりに達するときにまだ多くの時間が残っているならば、始まりに至るまで。要するに、リングバッファの周りを走り、時間がなくなるたびにフレームをレンダリングします。

+0

ありがとう、私はC#を選んでいただきありがとうございます。私はその性能に関するいくつかの情報を見つけようとしています。そして、多くの人々は、ゲーム開発のための適切なケースではないと言います。だから私は1000が本当に巨大だと思った。%-O- – joe

+0

@joe:C#は最近、一般的にかなり良いパフォーマンスを示している。それはまだ巧妙に作られたC++と同じレベルではありませんが、その違いはあなたのシナリオにとって重要ではありません。特に、重いGCはパフォーマンスをかなり悪くするので、私はあなたのオブジェクトの更新コードで 'new'を毎回見ています。同じように、あなたがまだそうしていなければ、すべての小さなクラスを構造体に変換します。 –

1

あなたの問題はゲーム開発に関連するものではなく、一般的なパフォーマンスの原則に関係すると思います。

おそらく、パフォーマンスを最適化するための複数の方法を検討する必要があります。

  • マルチスレッド化/並列化:非常に良い改善を達成することができますが、アプリケーションに複雑さを増やす可能性があります。C#4を使用している場合は、新しい並列ライブラリ
  • をVSのバージョンとエディションに応じて調べることができます。コード分析を有効にすることも、VSで利用できない場合はFXcopを使用することもできます。このツールは、良いアドバイスに(一般的なパフォーマンスのヒントについては、文字列ビルダVSを少しグーグルあなたのコードの複雑さを分析するために、あなたのコード
  • 使用ツール、特に循環的複雑度
  • のボトルネックを発見するためのツールをプロファイリング
  • 使用を提供することができます、値を変数の使用を減らす、方法のパラメータの順序を変更する(打ち性能チップのためもう少しグーグルコールグラフを低減
  • 文字列連結、等)、等)

Aより具体的なゲーム開発のためのヒント(ゲーム開発者の初心者から私は認めます): *オブジェクトを1つのセットではなくサブセットに分割しようとします...オブジェクトのグラフではなく、オブジェクトのリストを持つ方が効率的な場合があります。オブジェクト全体の代わりにグラフの単一ノードを更新することができます *表示されないオブジェクトの可能な更新を除外します

+0

有用なヒントありがとう!残念ながら私は1つ以上の正解を記入することはできません;( – joe

+0

pb :)役に立った –

関連する問題