タイムルーラー

注:今回紹介するコンポーネントはデバッグサンプルに入っています。 時を測る 前回紹介したFPSカウンターではゲーム全体のパフォーマンスを測定するには使えますが、どの処理がどれだけ時間が掛かっているかを判定するには不向きです。 例えば、ねこが大勢の敵をなぎ倒す「ねこ無双」というゲームを作っていて、敵が沢山出てきた時に処理落ちになった場合に最適化をする必要があったとします。 最適化ルールその3:「最も負荷の高い部分(ボトルネック)の処理を最適化する」 これは当然の話で、1フレーム内で10%しか消費していない処理よりも、50%消費している部分を最適化する方が効果的です。では、この高負荷の処理を発見するにはどうしたら良いでしょうか?ねこ無双の場合だと、敵が増えると処理落ちがするんだから真っ先に思いつくのは敵AI、敵のアニメーション、敵のコリジョン判定、敵の描画処理部分です。 しかし、必ずしもそうとは限りません。もしかしたら、敵の数ではなく戦っている場面の描画部分がもともと負荷が多かったのかもしれないし、敵を表示するレーダー部分かもしれません。 このボトルネックを発見するのに有用なのがリアルタイムプロファイラー、TimeRuler(タイムルーラー)です。TimeRulerでは、複数の処理時間を測定することができ、その結果をグラフでリアルタイムに表示してくれます。 上図の例では、青い部分が更新処理、黄色い部分が描画処理になっています。この状態で最適化する場合は更新処理部分を最適化するのが効果的だと言うことが一目で判ります。 アルゴリズムのチェック 理想的なアルゴリズムは計算量のオーダーがO(n)、もしくはO(n log n)になることです。例えば、敵を10体出現させたときの処理時間が1msだった場合、敵が100体になった時の処理時間が10ms~20ms以内に収まっていれば理想的なアルゴリズムを使っているということになります。逆に敵100体の処理時間が1,000msになってしまうのは、計算量オーダーがO(n^2)になっているアルゴリズムを使っている可能性があります。良くあるケースでは、コリジョン判定を単純な多重ループにしている時などです。 特に最近のゲームでは大量のオブジェクト数を処理するので、アルゴリズムの選択を間違えると、あっという間に処理が間に合わなくなってしまうので注意が必要です。 TimeRulerを使ってオブジェクトの数を10,20,…100と順々に増やしていき、それぞれの処理時間を測定してグラフにすることで問題のあるアルゴリズム部分を発見することができます。 瞬間最大負荷を測る TimeRulerはリアルタイムプロファイラーなので、瞬間的な負荷も視覚的に見ることができます。例えば同じフレーム内で大量の敵を一気に発生させると、敵の初期化処理に時間が掛かりすぎて、そのフレームだけ処理落ちするということがあります。こういった瞬間的な負荷はFPSカウンターで発見することは不可能ですが、TimeRulerを使うとグラフが一瞬大きくブレるので判ります。 また、TimeRulerを表示した状態でビデオに録画したり、動画をキャプチャーしておけば、こういった瞬間的な負荷を細かく調べることもできます。 TimeRulerを使う為の準備 TimeRulerコンポーネントはDebugManagerにあるフォントを使用するので、TimeRulerを追加する前にDebugManagerコンポーネントを追加する必要があります。// デバッグマネージャーの初期化と追 debugManager = new DebugManager( this ); Components.Add( debugManager ); また、必須ではありませんが、TimeRulerはインスタンス生成時にGame.ServicesにIDebugCommandHostインターフェースが追加されていると、trデバッグコマンドを登録します。DeubgCommandUIはIDebugCommandHostインターフェースを実装しているので、このコンポーネントを追加した後にTimeRulerを追加することでtrコマンドを使うことができます。// デバッグマコマンドUIの初期化と追 debugCommandUI = new DebugCommandUI( this ); // デバッグコマンドUIを最上面に表示させる為にDrawOrderを変更する debugCommandUI.DrawOrder = 100; Components.Add( debugCommandUI ); デバッグコマンドUIをTabキーを押して表示させた後に、trとタイプするとTimerRulerの表示/非表示の切り替え、”tr on”で表示、”tr off”で非表示にすることができます。 また、trコマンドには以下のオプションがあります。 log ログの表示/非表示の切り替え。 例) tr log…

7

FPSカウンター

注:今回紹介するコンポーネントはデバッグサンプルに入っています。 正確な測定には注意が必要 FPSカウンターは、一定時間内に(数秒程度)何フレーム更新できたかを計測した結果から、1秒間のフレーム数、FPS(Frame Per Second)を表示するという、非常に簡単な機能です。 ですが、正確なFPSを測定するには幾つかの注意が必要です。Game.IsFixedTimeStepの既定値はtrueになっているので、ゲームの更新と描画に掛かる時間が1msだとしても、見かけ上は16.6ms、つまり60FPSになってしまいます。また、描画時にV-Syncに同期するようになっているので、IsFixedTimeStepだけをfalseにしてもやはり60FPSになってしまいます。 FPSを正しく測定するにはゲームクラスのコンストラクタ内で以下の様なコードを実行する必要があります。graphics = new GraphicsDeviceManager( this ); graphics.SynchronizeWithVerticalRetrace = false; IsFixedTimeStep = false; これでFPS自体は正しく測定することができますが、IsFixedTimeStepをfalseに変更するということは、ゲームの更新の仕方が固定更新から、可変更新に変えるということです。もし、キャラクターを移動するコードが以下の様になっている場合に可変更新に変更すると、キャラクターの移動が速すぎてゲームがプレイ不可能になる場合があります。pos += speed; この問題を解決するには以下の様に、経過時間によって移動するようなコードになっている必要があります。float dt = (float)gameTime.ElapsedGameTime.TotalSeconds; pos += speed * dt; 固定更新、可変更新の振る舞いの違いについては、この投稿が参考になると思います。もし、既に固定更新でゲームを作っている場合にはFPSカウンターを使う意味はあまりありません。 GPUとCPUバランスに注意 また、CPUとGPUの負荷バランスが違う場合には、FPS値は参考になりません。例えば60フレームのゲームを作っている時にFPS値が丁度60フレームになっているからといって、必ずしもこれ以上の処理を追加できないと言うわけではありません。例えば、1フレームあたりの処理時間が、CPUが50%、GPUが100%近く消費している場合、CPU側にはまだ50%の余力があるにも関わらずFPSの値は60になるので、余力が無いように見えてしまいます。逆にCPU100%、GPU50%の状態でも同じです。 CPU、GPUバランスを調べる簡単な方法は、GPUの負荷を測定するにはUpdate内では何も処理をせずにDrawだけ実行し、CPUの負荷を測定するには逆にDrawの処理をしないようにする方法があります。ただし、Draw内にもCPU部分の処理があるので、もっと正確にCPUの負荷を測定するにはDrawPrimitiveのメソッドのみをコメントアウトする必要があります。 60FPSにならないんだけど IsFixedTimeStepとSynchronizeWithVerticalRetraceをtrueにした状態で、明らかにゲーム全体の処理が16.6ms以内で済んでいるのにも関わらず、FPSにはいつも59.xxしか表示されない。というのはおかしいと思う人もいるかもしれません。 これには3つの理由があります。ひとつめはTVの60フレームというのは実際には59.94(厳密に言えば60/ 100.1%)になるので、理論的に60と言う数値にはならないこと。ふたつめは、測定する場合に1フレーム以下の余りの時間分で誤差がでるということ。そして、ハードウェア的には59.94でフレームを更新していても、ソフトウェア的に測定ポイントまで戻ってくるまでの時間が微妙に変わってくるということです。 ですから、59.xxと言う数値を見たときには約60FPSと考えても問題ありません。 FpsCounterコンポーネントの使い方 FpsCounterコンポーネントはDebugManagerにあるフォントを使用するので、FpsCounterを追加する前にDebugManagerコンポーネントを追加する必要があります。// デバッグマネージャーの初期化と追 debugManager = new DebugManager( this ); Components.Add( debugManager ); また、必須ではありませんが、FpsCounterはインスタンス生成時にGame.ServicesにIDebugCommandHostインターフェースが追加されていると、fpsデバッグコマンドを登録します。DeubgCommandUIはIDebugCommandHostインターフェースを実装しているので、このコンポーネントを追加した後にFpsCounterを追加することでfpsコマンドを使うことができます。 デバッグコマンドUIをTabキーを押して表示させた後に、fpsとタイプするとFPSの表示/非表示の切り替え、”fps on”で表示、”fps off”で非表示にすることができます。//…

1

デバッグサンプル

2010/09/17 追記: XNA Game Studio 4.0用のサンプルをhttp://higeneko.net/hinikeni/sample/xna40/DebugSample.zipにアップしました。詳細は「サンプルコードをXNA 4.0向けに更新」を見てください。 2009/06/25 追記: XNA GS 3.1用のサンプルを http://higeneko.net/hinikeni/sample/xna31/DebugSample.zipにアップしました 2009年1月24日追記: サンプルプログラムのキーボード処理部分でテンキーの0を押すと1が入力されるバグを修正、アップデートしました。バグがあった場所はGameDebug/KeyboardUtils.csファイル内のInitializeKeyMapメソッド内の初期化コード部分です。AddKeyMap( Keys.NumPad0, "10" )となっているのをAddKeyMap( Keys.NumPad0, "0" )にする事で修正できます。連絡してくださったDERNAさんに感謝します。   デバッグ3種の神器 ゲーム開発現場で最も使われているゲーム内で動作するデバッグ用の機能といえば以下の3つがあります。 FPSカウンター リアルタイムプロファイラー デバッグコマンド 市販されているPCゲームの中にはオプション画面でFPSカウンターを表示できるようになっているものもあるので、パフォーマンスの指標として有名です。後のふたつについては一般にはあまり知られていませんが、ゲーム開発現場、特に北米のゲーム開発現では良く目にする機能です。 前回紹介したGamefest Japan 2008のデモでも、これらの機能を使っています。そこで、今回は前回のデモからデバッグ機能だけを抜き取ったサンプルを作りました。  http://higeneko.net/hinikeni/sample/DebugSample.zip 前回と同じく、フォントはConsolasを使用しています。Consolasフォントが無い場合はビルドエラーになるので、以下のURLからConsolasフォントをダウンロードするか、フォント名を変更するようにしてください。 https://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&displaylang=en 使い方 サンプルを起動すると、画面右上に使い方が表示されます。 FPSカウンターの表示 Aボタン、またはAキー TimeRulerの表示 Bボタン、またはBキー TimeRulerログ表示 Xボタン、またはXキー デバッグコマンドUIの表示 Tabキー サンプルプログラムの終了 Backボタン、またはEscapeキー デバッグコマンドUIはキーボード入力からデバッグ用コマンドを実行します。Xbox 360でもUSBキーボードを本体に繋げることで使うことができます。デバッグコマンドUIには元々使えるコマンドとして画面をクリアするclsコマンド、登録されているコマンドを表示するhelpコマンドがあります。基本的にWindowsにあるコマンドシェルと使い方は一緒で、上下キーで最近使ったコマンドのヒストリを表示する機能もあります。 このデモでは、DebugSampleGame.cs内には独自のデバッグコマンドを追加するサンプルコードが含まれていて、ここではposコマンドを追加して、画面上に表示される「+」マークの位置を表示したり、変更できるようになっています。下の動画では見づらいですが、最初は左上にあった白い点がposコマンドによって画面下中央に移動しているのが判ると思います。 サンプルに含まれるファイル このサンプルに含まれるファイルには、デバッグ機能の使い方のサンプルコードが入ったDebugSampleGame.csファイルの他に、デバッグ機能を提供する以下の8つのファイルがあります。 DebugSample/GameDebug/DebugCommandUI.cs デバッグコマンドUIクラス DebugSample/GameDebug/DebugManager.cs デバッグ用のコンテントを格納する為のゲームコンポーネント…

7

Gamefest Japan 2008 デモプログラム

2010/9/17 追記: XNA Game Studio 4.0のサンプルをhttp://higeneko.net/hinikeni/sample/xna40/GamefestJapan2008Demo.zipにアップしました。変更点は「サンプルコードをXNA 4.0向けに更新」に書いてあります。 2010/05/16 追記: マテリアルバッチ描画時のDrawIndexedPrimitiveメソッドへの引数設定が間違っていたのを修正しました。 2009/06/25 追記: XNA GS 3.1用のサンプルを http://higeneko.net/hinikeni/sample/xna31/GamefestJapan2008Demo.zipにアップしました 2008/12/26 追記: デモプログラムの更新、キーボード入力で操作できるようになりました。 やっと終わりました 今年の9月に行われたGamefest Japan 2008のプレゼンテーション資料が先月公開されました。 http://msdn.microsoft.com/ja-jp/xna/cc723908.aspx 私も僭越ながら2つのセッションを担当させて頂き、そのプレゼンテーション資料も公開されています。XNA Game Studioでのゲーム開発においてのパフォーマンス改善について戦略的手法と実践的な手法、主にシステムレベルでの最適化の効果の程を紹介させていただきました。 http://download.microsoft.com/download/0/4/2/04291420-033b-4f46-b87d-de64a2dc6bac/X5.zip 本当はプレゼン時にサンプルプログラムの配布したかったのですが、本業の方のXNA Framework作業の方が佳境の最中で、その合間に書いたコードだったので非常に汚いコードであったのと、先月のXNA Game Studio 3.0のリリースまでその忙しさが続いたので、なかなか公開することができませんでした。っていうか、コメントを追加するのは当然として、他にも3.0対応にしたり、再利用可能なコンポーネントを使いやすく書き換えたりして、発表時のコードよりも4,000行近く増えてしまったのも、今まで時間が掛かった原因でした。 ともかく、なんとか人に見せられる程度の体裁は整えたので、デモプログラムを公開します。 http://higeneko.net/hinikeni/sample/GamefestJapan2008Demo.zip 解凍したフォルダの中には以下の3つのソリューションファイルがあるので、好きなソリューションファイルを使ってください。いずれのプロジェクトを開くのにもXNA Game Studio 3.0が必要です。また、Windowsで実行するにはシェーダーモデル2.0以上のビデオカードが必須になります。 DemoWin.sln Windows用のソリューションファイル DemoXbox.sln Xbox 360用のソリューションファイル Demo.sln Windows/Xbox 360の両方のプロジェクトが入ったソリューションファイル フォントは私がプログラムする時に使っている等幅フォントのConsolasを使用しています。Consolasフォントが無い場合はビルドエラーになるので、以下のURLからConsolasフォントをダウンロードするか、フォント名を変更するようにしてください。 https://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&displaylang=en このサンプルプロジェクトのコード、アセットは非商用、商用に関わらず、自由に使ってかまいません。ただし、一部のコードはクリエータークラブオンラインのMesh Instancingのコードを流用、または変更しているので、それらのコードのライセンスについては付属されるMicrosoft Permissive License.rtfに沿います。 http://creators.xna.com/en-US/sample/meshinstancing で、お約束ですが、このサンプルコードやアセットを使用したことで発生したいかなる問題にも当方は責任を負いません。…

9

招待サンプル

今日は招待サンプルを紹介します。 Xbox Live!の機能のひとつに、フレンドリスト内の友達と一緒にネットワークゲームをプレイしたいときに誘える招待機能があります。XNA GS 3.0ではこの招待機能がサポートされています。招待するケースとしては以下の二つのケースがあります。 同じゲームをプレイしている時(In-Title Invites) 違うゲームをプレイしている時(Cross-Title Invites) XNA GS 3.0上では、このどちらのケースでもNetworkSession.InviteAcceptedイベントが発生します。このイベントを受け取った時に、NetworkSession.JoinInviteメソッドを呼ぶことで招待された側が招待した側のセッションに接続できるようになっています。以下はイベントハンドラへの登録と、ハンドラ内での処理の例です。NetworkSession.InviteAccepted += InviteAcceptedEventHandler;void InviteAcceptedEventHandler(object sender, InviteAcceptedEventArgs e) { // 現在のセッションから抜ける if (networkSession != null) { networkSession.Dispose(); networkSession = null; } // 招待されたセッションに入る networkSession = NetworkSession.JoinInvited(maxLocalGamers); } 同じゲームをプレイしている場合は、通常のNetworkSessionの振る舞いと殆ど同じですが、違うゲームをプレイしている場合は振る舞いの仕方が変わってきます。ただし、これらの処理は全てOS側で行われるのでゲーム開発者は前述のInviteAcceptedイベントの実装をするだけです。 Xbox 360上で同じゲームが既にインストールしている場合は自動的にゲームが起動され、その直後にInviteAcceptedイベントが発生します。 クリエーターゲーム(開発中のゲームやピアレビュー中のゲーム)の場合は、招待した人が同じゲームを持っていない場合に、その旨を伝えるメッセージが表示されます。 コミュニティゲームの場合、ユーザーがそのゲームを持っていない場合はマーケットプレースに自動的に移動、該当するゲームをダウンロードするかのメニューが表示され、ダウンロード後に自動的にゲームが起動されます。 Windows上の場合、上記のように自動的なダウンロードや起動するといった機能がないので、ユーザーが手動で行う必要があります。 テスト時の注意 招待機能はXbox Live!の機能なので、ネットワークゲームのテストの様にシステムリンク(ローカル)を使ってテストできるのと違い、クリエータークラブ会員になっているゲーマータグが二つ必要なことに注意してください。

1

セーフエリア・サンプル

今回はセーフエリア サンプル(Safe Area)の紹介をします。 世の中には様々なTVがある ゲームをプレイする人達のTV環境は実に様々なものがあります。 オーバースキャンとアンダースキャン HDTVとSDTV ワイドスクリーンと4:3 コンポーネント接続とコンポジット接続 60cm(2フィート)と3m(10フィート) オーバースキャンとセーフエリア PCモニタなどのイメージ全体を表示するアンダースキャン方式に対して、HDTV、SDTVのどちらも、その多くがイメージ全体を表示することのできないオーバースキャン方式を採用しています。 イメージ全体を表示することができないので、ゲームでスクリーン座標の左上(0, 0)に文字を表示したりするとオーバースキャン方式のディスプレイでは文字が読めなくなってしまいます。 こういったオーバースキャン方式のディスプレイには以下の二つのタイプのセーフエリアがあります。 タイトルセーフエリア(80%の領域) アクションセーフエリア(90%の領域) タイトルセーフエリアには文字などの大事な情報を表示する領域で、下図の青い色の領域になります。アクションセーフエリアは殆どのディスプレイで表示される領域です数では緑色の枠内の領域になります。そして、赤い部分はディスプレイによっては全く表示されない領域です。 この画像は1280x720の画像なので、ゲームのインターフェースのデザインなどをするときにガイドラインとして使えるようになっています。 さて、タイトルセーフエリアに大事な情報を表示するからといって、Xbox 360、PCの両方で文字列をタイトルセーフエリアに描画した場合、Xbox 360上での見た目は良いとしても、PC上だと無駄にまわりのスペースが空いてしまいます。 そこで、XNA GS 3.0から追加されたViewport.TitleSafeAreaプロパティを使います。このプロパティPC上では元のビューポートのサイズと一緒になりますが、Xbox 360上ではビューポートの80%の領域、つまりタイトルセーフエリアを返します。 Safe Areaサンプル内にあるAlignedSpriteBatchクラスでは文字列をタイトルセーフエリアの右端、左上といった位置情報を指定して描画できるようになっています。 また、SafeAreaOverlayはコンポーネントになっていて、Xbox 360、デバッグの設定の時のみにタイトルセーフエリアの外側の領域を赤く表示するようになっています。 実際のゲーム開発の場合に気をつける事としては、 3Dゲームの場合、操作するキャラクターが画面中央に描画しているかぎりはセーフエリアを気にすることがありません。 スクロールタイプの2Dゲームの場合、メインキャラクターはタイトルセーフエリア内に表示するようにします。サンプルでは猫を移動することで画面をスクロールするようになっていますが、猫は常にタイトルセーフエリア内にいます。 通常は全ての画面全体を描画するべきですが、シューティングゲームのようなものだと、あらかじめアクションセーフエリア外の部分を黒く表示して自機の移動範囲を判りやすくするという方法もあります。 インターフェースの全てをタイトルセーフエリアに納める必要はない。下図はRoboGameをXbox 360上で実行したときの画面にセーフエリアを重ねた画像です。ゲームプレイにとって大事なプレイヤーのHPや武器の残弾数などの表示はタイトルセーフエリアに表示されていますが、ゲームプレイに支障のないインターフェースのデザイン的な部分はアクションセーフエリアに表示されています。 解像度とアスペクト比 TVモニタの場合は標準解像度の640x480から、1080pの1980x1080まで様々な種類があり、またアスペクト比も16:9と4:3の二種類があります。 Xbox 360向けのゲームで様々な解像度とアスペクト比に対応するもっとも簡単な方法は720p、つまり1280x720を使うことです。Xbox 360には1/4~4倍の解像度にスケーリングしてくれるハードウェアがあるので、720pを設定するとどの解像度でも自動的にスケーリングしてくれます。また、720pのアスペクト比は16:9ですが、4:3のTVを使った場合にはTV上では以下のようにレターボックス表示になります。 モニタとの距離 ゲーム開発中、PCモニタとの距離は60センチ程度ですが、実際にリビングルームでゲームをする場合は3メートル程の距離があります。と、米国では言ってますが日本の住宅事情を考えると、もうちょっと短い距離になりそうですが、要点としては自室でPCモニタを見ている感覚でゲームを作ってしまうと、リビングルームでプレイする時に文字が小さくて読めないという問題が発生します。目安としては720pの解像度で20ポイント以上の大きさの文字列をつかうことです。 TVとの距離の他にも 細い線を描画しない、特に水平線を書いた場合にインターレース方式のTVではちらつきが発生します。 明るい赤い文字を使用しない。NTSCの場合、にじみの原因になります。 大事な情報は色だけでなく、サイズや形を変えたり、アニメーションするようにする。これは赤と緑の色の区別がつきにくいという色覚障害が日本人では男性の20人に1人、女性は500人に1人という低くない割合でいるので、こういった配慮をすることでより多くの人達が快適に遊べるようになります。パズルゲームで色を合わせるといった場合は、色だけでなく模様や形状を変えると良いでしょう。 レイアウトに注意 3Dゲームのシーンを描画する時には気にする必要はあまりありませんが、メニュー画面などをデザインする時にはセーフエリアを意識してデザインする必要があります。特に、パズルゲームやテーブルゲームなどの固定画面型の2Dゲームの場合にはレイアウトがそのままゲームプレイに影響するので、画面一杯使ってレイアウトした結果、TV上ではゲームをプレイするのが不可能になってしまったなんて事にならないよう注意しましょう。 元ネタ:Safe Areaに含まれるドキュメントファイルから

1

ローカライゼーション・サンプル

Creators Club Onlineに以下の3つの新しいサンプルが追加されました。 ローカライゼーション サンプル(Localization) セーフエリア サンプル(Safe Area) 招待 サンプル(Invites) 一気に紹介すると長くなるので、三回に分けてそれぞれのサンプルを紹介していきます。今回はローカライゼーション サンプルについて紹介します。 ローカライゼーション コミュニティゲームでゲームを投稿する場合、配信地域を選ぶことができます。現状ではアメリカ、カナダ、イギリス、フランス、イタリア、そしてスペインの6カ国で、2009年の前半には日本が加わり7カ国になります。世界の複数の国々の人達に自分の作ったゲームを楽しんで貰うためには必要な作業としてローカライズがあります。そこで、このサンプルではローカライズされた文字列とアセットの使い方のコードが含まれています。 ローカライズされた文字列表示 このサンプルでは言語別のリソースファイル(.resxファイル)を用意し、ゲームクラスコンストラクタの中で実行環境の言語情報を以下のコードのように指定して文字列を変更しています。Strings.Culture = CultureInfo.CurrentCulture; SpriteFontDescriptionクラスから派生したLocalizedFontDescriptionクラスに複数のリソースファイルを指定できるようになっていて、ここに各言語の文字列が入ったリソースファイルを指定し、コンテント・パイプライン内でLocalizedFontProcessorによって変換されます。 言語別のリソースファイルは、リソース名.言語コード.resxのようになっています。このサンプルではリソース名がStringsになっていて日本語のリソースファイル名はStrings.ja.resxとなっています。この言語コードはISO 639-1で定義されているアルファベット2文字になっています。 殆どの場合は言語コードを指定するだけで済むのですが、言語コードだけでは足りなくなる場合もあります。例えば、同じ英語でもアメリカの場合はcolorでもイギリスの場合はcolourと違いがあります。その場合は言語コードと国名コードの組み合わせを使います。国名コードはISO 3166-1で定義されているアルファベット2文字を使います。アメリカの英語の場合はen-US、イギリスの英語の場合はen-GBとなります。 この言語コード-国名コードの組み合わせをカルチャ名と呼び、カルチャを表すCultureInfoクラスを生成する時に以下のコードのようにして使用します。Strings.Culture = new CultureInfo(“en-GB”); ローカライズされたアセット読み込み ローカライズ作業の大半は文章の翻訳になりますが、中にはテクスチャ等のアセット自体をローカライズしたい時があります。このサンプルでは読み込むアセット名を前述のリソースファイル名と同じように、アセット名.カルチャ名の組み合わせであることを前提として使うGetLocalizedAssetNameメソッドがゲームクラスに宣言されていて、国別の国旗テクスチャを変更しています。 以下はコミュニティゲームがサポートする国と言語の表です。 国名 公用語 言語コード 国名コード カルチャ名 アメリカ 英語 en US en-US カナダ 英語、フランス語 en,fr CA en-CA,fr-CA イギリス 英語 en GB en-GB フランス フランス語 fr FR fr-FR…

1

PIXを活用する その2

前回に続いてPIXの機能と、私が実際にどんな状況でPIXを使って来たかを交えて紹介します。 ちなみにPIXはピクスと呼びます。たまにピックスと呼ぶ人もいますが私のまわりではピクスが多いです。 RenderウィンドウからDebug This Pixelメニューを使って表示されるDebuggerタブで、前回はDebug VertexやDebug Pixelをクリックしてのシェーダーのデバッグを紹介しましたが、今回はEvent部分をクリックして表示される情報について説明します。 Debuggerタブ内のそれぞれのピクセル情報の上の部分には、そのピクセルを描画したイベントが表示されます。上の場合はDrawIndexedPrimitiveとなっています。ここをクリックすると、左下にあるイベントウィンドウ内で該当するイベントが選択されます。 描画順序のチェック PIXは描画に関する全てのイベントとその情報を記憶しているので、好きなイベントを選択することで描画の課程を調べることができます。これはVisual Studio上でブレークポイントを設定するといった未来時間一方向へのデバッグに対して、PIXではキャプチャーしたフレーム内での時間を自由に移動できるデバッグをすることができます。 イベントを選択した状態でRenderタブを選択すると、選択されたイベント処理が終わった直後の描画結果、つまりフレーム描画の途中結果を見ることができます。 不透明のオブジェクトを描画する場合、手前から奥にむけて順に描いていくのが効果的なのですが、普通にゲームをプレイしている限りでは描画順序は判らないし、描画コードを追いかけるのにも負担が掛かります。PIXを使うとそういった描画順序をここで簡単に確認できます。例えば、おっさんを描いている途中のこの段階で、遠景によく使われるスカイドームのオブジェクトが既に描画されている場合は、最後に書くべきスカイドームが先に描画されているという問題を発見することができます。 Meshデータの表示 Draw系のイベントを選択した時、Meshタブにはその描画がどの様に行われたかの詳細な情報が表示されます。Meshタブの上の方には三つのワイヤーフレーム画面が表示され、左から順に以下のようになっています。 Pre-Vertex Shader Post-Vertex Shader Viewport Pre-Vertex Shader画面には頂点シェーダーに送られる頂点、通常はローカル座標のモデルが表示されます。Post-Vertex Shader画面には頂点シェーダー処理後、つまり射影座標内でのモデルが表示されます。そして最後は透視変換後のビューポート座標でのモデルが表示されるViewport画面となっています。 そして、それら三つの画面の下には頂点シェーダーに入力頂点のリストを表示するPreVSタブと、頂点シェーダー処理後の頂点リストを表示するPostVSタブがあります。 頂点シェーダーを書いている場合に良くあるのが頂点変換ミスです。この場合、画面に変な形のモデルが表示されている場合は頂点シェーダーに問題があるというのはすぐに判るのですが、画面に何も表示されない場合は頂点変換ミスの他にもピクセルシェーダー内でのミスという場合もあるので、Viewport画面にちゃんと表示されているかを確認することで、頂点シェーダー、ピクセルシェーダーのどちらに問題があるかを絞り込む事ができます。 頂点リスト内の頂点はクリックして選択することができ、選択された頂点は下図の様にモデル表示画面内と頂点リスト内で黄色で表示されます。また、頂点リスト内では選択された頂点が属する三角形の他の頂点が赤色で表示されます。 Deviceのステートの表示 Meshタブ内で頂点シェーダーが正しく動作しているのを確認したけど、まだモデルが表示されない。そんな時に調べるのがDeviceステートです。この情報はEventsウィンドウに表示されているイベントの左側にある数字(下図の黄色い部分)をダブルクリックすることで表示されます。 Detailsウィンドウには新たにDeviceタブが追加表示されます。このDeviceタブの中には更に複数のタブが追加されます。それぞれのタブにはカテゴリ別のDeviceのステート情報が記載されています。 私がここでよく使うのはPixel StateタブとOutput Stateタブです。Pixel Stateタブ内ではCullingやViewport、そしてAlphaテストなどの情報が役に立ちます。特にCullingが逆になっているとモデルがちゃんと表示されないし、Alphaテストに間違った値を設定しているとモデルが全く表示されないということもあります。また、Samplersセクションでは、どんなテクスチャが設定されているかを調べることができます。このSamplers部分で設定されているテクスチャの数字をダブルクリックすると、以下の様に設定されているテクスチャの詳細を見ることができます。 グロスマッピング、ディテールテクスチャといった、描画結果への反映が少ないようなテクスチャや、テクスチャに色以外の情報を入れている場合はここで調べたりしています。 Output Stateタブ内ではデプステストの有無、ブレンディングステートを調べるのに使っています。特にアルファブレンドを使っている場合の見た目では判りづらいステートの違いはここで調べています。 PIXを活用しよう 急ぎ足でしたが、二回に渡ってPIXの機能を紹介しました。2Dゲームと違って3Dの場合は実に様々なステートがあり、2Dゲームの場合はトライ&エラーでどうにかなった問題も3Dゲームの場合はトライ&エラーをするには時間が掛かりすぎてしまいます。そういった問題を解決するのにPIXは非常に強力なツールです。シェーダーのサンプルは沢山ありますが、シェーダーサンプル単体では問題なく動いたのにゲームに組み込んでみたら、動かなくなったなんて話を良く聞きます。そんな時にもPIXを使うと、なぜ動かないのかを調べることができます。 また、Xbox 360向けに開発している場合でも、開発しているPCにShader Model 3.0のビデオカードがあれば、Windows用のプロジェクトに変換して実行できるようにしておけば、殆どの場合は描画に関するデバッグは問題なくできます。そのままデバッグできない例としてはXbox 360限定のvfetchを使った場合ですが、vfetchはあくまで頂点データのフェッチ用の命令なので、シェーダー全体のコード量に比べると非常に小さく、頂点データをフェッチした後のシェーダーはWindows上でもデバッグできます。 私は、初代Xboxの頃からPIXを使って7年くらい経ちますが、今では描画に問題があったらすぐにPIXを立ち上げて調査するというのが習慣化していて、私にとってPIXはゲーム開発に必須のツールとなっています。 綺麗な絵を出すシェーダープログラミングに比べると地味なものですが、これを機にPIXに触れてもらえば幸いです。

1

Dream-Build-Play 2008 コンテスト受賞者発表

Dream-Build-Playコンテストの受賞者が発表されました。今年は去年に増してクオリティの高いゲームが多数エントリーしました。そこで今回は受賞作品とその動画を紹介します。 第1位 CarnyValue: Showtime 第2位 Battle Tennis http://www.battletennis.com/ 第3位 Weapon of Choice http://www.mommysbestgames.com/ 第4位 WeHurricaneX2 これらの受賞作品のいくつかは制作者サイト内でコミュニティゲーム配信予定ということアナウンスされているものもあるので、これらの受賞ゲームに加え、惜しくも受賞を逃したけどクオリティの高いゲームがコミュニティゲームに配信されるではないでしょうか?

1

XNA Game Studio Connect関連の新機能

XNA Game Studio Connectに関連する新機能として以下の二つがあります。 スクリーンキャプチャー機能 配置の高速化 スクリーンキャプチャー 以前から要望として多かった機能の一つとしてXbox 360上で動作しているゲームのスクリーンキャプチャーがあります。XNA GS 3.0ではこのスクリーンキャプチャーが使えるようになりました。 スクリーンキャプチャーはゲームをデバッガにアタッチした状態、つまりVisual Studio上からF5キーを押して実行した時と、XNA Framework Remote Performance Monitorを使った時にしか使えないことに注意してください。 キャプチャ自体は非常に簡単でXNA Game Studio Device Centerでキャプチャーしたいデバイスのアイコンの右クリックメニューからTake Screen Captureを選択するだけです。 スクリーンキャプチャーされた画像はピクチャフォルダにデバイス名-番号というファイル名、PNG形式で保存されます。複数のスクリーン画像を続けてキャプチャーすると、デバイス名-1.png、デバイス名-2.pngといった感じに複数の画像ファイルが作られます。 Xbox 360上で動作しているゲーム画面をブログなどで紹介するときには、今まではデジカメで画面を撮ったり、自前でキャプチャープログラムを書かないといけませんでしたが(こんな方法もあったりしました)、これからはキャプチャー、ブログ書き込みプログラム上にドラッグ&ドロップするだけで、以下のようなスクリーンショットをブログに載せることが簡単になりました。 配置の高速化 XNA GS 2.0以前ではXbox 360上でゲームを開発している時にゲームの配置、特にコンテントの配置に時間が掛かるという問題がありました。XNA GS 3.0ではこの問題を解決するために二つの改良が施されました。 一つ目はファイルの圧縮です。 XNA GS 3.0ではプロジェクトプロパティにContent Buildタブが追加され、その中にコンテントパイプラインの出力ファイルの圧縮オプションが追加されました。 デフォルトではWindows用プロジェクトでは圧縮せず、Xbox 360用プロジェクトでは圧縮するようになっています。Windows用とXbox 360用のプロジェクトでデフォルトの設定が違うのは次の理由があります。PCにはXbox 360より高速で大容量なHDDがあり、圧縮に掛かる時間に見合うだけのメリットが少ないのに対して、Xbox 360ではコミュニティゲームの150MBという容量制限があるのと、圧縮した方がコンパイルと配置の全体時間の短縮になるからです。もちろん、このオプションは自由に変えられるようになっています。 圧縮率はコンテントによって左右されますが、通常は元のサイズの70%~50%程度です。中には元のサイズの25%まで圧縮されたというケースもありました。この圧縮効果によって、配置に掛かる時間は三割から二倍程度速くなりました。 そして、二つ目は配置用のプログラムのチューニングです。 XNA Game Studio Connectの待機画面では、メインスレッド以外の5つのスレッドは暇を持て余していたので配置プログラムをマルチスレッド用に特化させることで配置に掛かる時間が大幅に短縮されました。 この二つの相乗効果によって、Xbox 360へのコンテントの配置が劇的に速くなりました。

1