C#のようなマネージ言語を使用してPC用のゲームを作成する際に、どのような落とし穴に遭遇し、どのように解決しましたか?
C#のようなマネージ言語を使用してPC用のゲームを作成する際に、どのような落とし穴に遭遇し、どのように解決しましたか?
回答:
私はJavaについてあまり知らないので、これは.net開発者の観点からです。
一番大きいのはゴミです。Windowsの.NETガベージコレクターは素晴らしい仕事をしており、ほとんどの場合、赤ちゃんが座っていなくても逃げることができます。Xbox / Windows Phone 7では、これは別の問題です。数フレームごとにストールが発生する場合、ガベージコレクションが問題を引き起こしている可能性があります。現時点では、1MBの割り当てごとにトリガーされます。
ゴミを処理するためのヒントを次に示します。現実にはこれらのほとんどについて心配する必要はありませんが、いつか役に立つかもしれません。
GC.GetTotalMemory()
画面に描画します。これにより、ゲームが使用する割り当て済みバイトの概算値が得られます。それがほとんど動かないなら、あなたは大丈夫です。急速に上昇する場合、問題があります。GC.Collect()
。大規模な割り当ての大部分が途切れていることがわかっている場合は、システムに知らせるだけで十分です。GC.Collect()
すべてのフレームを呼び出さないでください。ガベージとそのすべてを維持するのは良い考えのように思えるかもしれませんが、ガベージコレクションよりも悪いのはガベージコレクションを超えていることだけを覚えておいてください。StringBuilder
(用心が、StringBuilder
特効薬はなく、まだでき配分を引き起こす!。これは、文字列の末尾に番号を追加するような単純な操作は、ごみの驚くべき量を作成できることを意味します)、または使用してforeach
使用してコレクションをループをIEnumerable
もあなたは知らなくてもゴミを作成することができるインタフェースを(例えば、foreach (EffectPass pass in effect.CurrentTechnique.Passes)
一般的なものです)IDisposable
アンマネージリソースを含むクラスで使用することを忘れないでください。これらを使用して、GCがそれ自体を解放できないメモリをクリーンアップできます。考えるべきもう1つのことは、浮動小数点のパフォーマンスです。.NET JITerはかなりの量のプロセッサ固有の最適化を行いますが、SSEまたはその他のSIMD命令セットを使用して浮動小数点演算を高速化することはできません。これにより、ゲームのC ++とC#の速度が大きく異なる可能性があります。モノを使用している場合は、利用できる特別なSIMD数学ライブラリがあります。
典型的なパフォーマンスの落とし穴は、ゲームの設計/開発におけるガベージコレクターを考慮していません。ガベージの生成が多すぎると、ゲームで「しゃっくり」が発生する可能性があります。これは、GCが長時間実行されると発生します。
C#の場合、値オブジェクトと「using」ステートメントを使用すると、GCからの圧力を軽減できます。
using
文はガベージコレクションとは関係ありません!IDisposable
オブジェクト用です-アンマネージリソース(つまり、ガベージコレクターによって処理されないリソース)を解放するためのものです。
C#でゲームを書く際に遭遇した最大の問題は、まともなライブラリがなかったことです。私が見つけたもののほとんどは、直接ポートですが、不完全であるか、マーシャリングのパフォーマンスが大幅に低下するC ++ライブラリのラッパーです。(OGREライブラリの場合はMOgreとAxiom、Bullet物理ライブラリの場合はBulletSharpについて具体的に説明しています)
マネージ言語(Interpretedとは異なり-JavaもC#も実際に解釈されなくなりました)は、実際に言語を遅くするもの(マーシャリング、ガベージコレクション)を十分に理解している場合、ネイティブ言語と同じくらい速くなります。本当の問題は、ライブラリ開発者がまだ気付いていないことだと思います。
他の人が言ったように、GCコレクションの一時停止は最大の問題です。オブジェクトプールの使用は、一般的なソリューションの1つです。
C#とJavaは解釈されません。これらは中間バイトコードにコンパイルされ、JITの後、ネイティブコードと同じくらい高速になります(または、取るに足らないほど十分に近くなります)。
私が見つけた最大の落とし穴は、ユーザーエクスペリエンスに直接影響するリソースを解放することです。これらの言語は、C ++のように決定論的なファイナライズを自動的にサポートしません。C++のように、予期しない場合は、メッシュが破壊されたと思った後にシーンの周りに浮かぶ可能性があります。(C#はIDisposableを介して決定論的なファイナライズを達成しますが、Javaが何をするのかわかりません。)
それ以外に、マネージド言語は、ゲームが必要とする種類のパフォーマンスを、クレジットを獲得するよりもはるかに多く処理することができます。適切に記述されたマネージコードは、不十分に記述されたネイティブコードよりもはるかに高速です。
IDisposable
タイムクリティカルで管理されていないリソースの確定的なクリーンアップを許可しますが、ファイナライズまたはガベージコレクターに直接影響しません。
JavaもC#も解釈されません。両方ともネイティブマシンコードにコンパイルされます。
それらとゲームの両方の最大の問題は、ゲームプレイ中にガベージコレクトしないようにコーディングする必要があることです。それを達成するためにジャンプしなければならないフープの数は、そもそもそれらを使用する利点をほとんど上回っています。これらの言語をアプリケーションやサーバーのプログラミングに使用するのを楽しくする機能のほとんどは、ゲームプログラミングでは使用しないでください。
これらのような言語(またはXNA、TorqueXエンジンなどのツールを使用)でゲームを作成するときに見られる大きな落とし穴の1つは、同等のゲームを作成するために必要な専門知識を持つ優秀な人々のチームを見つけるのに苦労することですC ++やOpenGL / DirectXで簡単に人を見つけることができます。
ゲーム開発業界は、C ++にまだ非常に重くのしかかっています。大きなゲームや洗練された小さなゲームをプッシュするために使用されるツールとパイプラインのほとんどはC ++で書かれており、私が知る限り、 XBox、PS3、およびWii用のgetは、C ++との互換性がある場合にのみリリースされます(最近では、XBoxツールセットがより管理されている可能性があります。
今すぐコンソール用のゲームを開発したい場合、XBoxでXNAとC#を取得し、XBox Live Indie Gamesと呼ばれるゲームライブラリのサイド部分でのみ取得します。コンテストなどで勝った人の中には、ゲームを実際のXBox Live Arcadeに移植するために選ばれる人もいます。それ以外は、PC用のゲームを作成する計画です。