8.1 コンテンツとゲームの統合
8.1.1 XNA Game Studioビルド処理の拡張
これまでも、ゲームプログラム本体と切り離された外部にあるデータ、すなわちフォントや画像、3D モデル、エフェクト、オーディオなどを扱ってきました。前述したように、これらのデータは事前に Content サブプロジェクトに追加登録され、ビルド時にゲームに最適な状態に変換されます。実行時に動的にデータを読み込んで変換することは、多くのゲームにとっては無駄な作業となってしまいます。データを事前にビルドすることによって、不要なデータの削除や圧縮、または暗号化といったことが柔軟に行えます。
このように、ビルド時にプロジェクトに含まれているファイルをゲームが読み込める形式に変換する一連の工程をコンテンツパイプラインと呼びます。コンテンツパイプラインは、プロジェクトに登録されているファイルをビルド時に読み込み、適切な変換処理を経てアセット(XNB ファイル)として出力します。これまで、JPEG や PNG 画像を読み込んで Texture2D オブジェクトとして利用してきたように、ゲームのコンテンツとして最低限必要になる画像、モデル、フォントなどは標準でサポートされています。
加えて、必要であれば開発者が任意でコンテンツパイプラインを拡張できます。ゲームのアルゴリズムは開発者が記述するものですが、進行手順などのデザインはデザイナが担当するべきものです。マップやキャラクタの配置、画面に表示するメッセージ、台詞の順序や表示タイミングなど、これらの情報は原則としてプログラムの中にコーディングされるべきではなく、外部ファイルでスクリプタやデザイナが調整できるようにするべきです。このようなゲーム独自の情報も、コンテンツパイプラインを拡張することで容易に XNA Game Studio に統合できます。
8.1.2 コンテンツパイプラインの仕組み
コンテンツパイプラインの基本的な構造と仕組みは「コンテンツ管理」でも説明しました。ここで重要となるのが、元となるファイルを読み込み処理用のデータに変換するインポータと、インポータから受け取ったデータを処理してゲーム用のアセットとして出力するプロセッサの存在です。インポータやプロセッサを、ゲームとは異なる別のプロジェクトとして開発することで、対象のファイルをゲームのプロジェクトで利用できるようになります。XNA Game Studio は標準でサポートされていないファイルの対応だけではなく、入力または出力の一方だけをカスタマイズすることもできます。
図1は、より詳細なコンテンツパイプラインの概念図です。入力されるファイルはソースアセットとも呼ばれ、ビルド時にインポータによって読み込まれます。インポータは System.IO 名前空間の入力機能などを使ってファイルを読み込み、プロセッサで処理するための適切なマネージ型のオブジェクトに変換して返します。
インポータから得られたデータはプロセッサに入力され、プロセッサは入力されたデータとパラメータを使って変換を行い出力します。出力されたデータは専用のタイプライトと呼ばれるプログラムによって XNB ファイルに書き込まれます。ここで生成されたXNBファイルを正確にはコンパイル済みアセットと呼びます。コンパイル済みアセットは、実行時にタイプリーダと呼ばれるプログラムによって読み込まれ ContentManager クラスのオブジェクトを通してゲームに渡されます。
プロセッサの出力が XNA Framework が標準でサポートしている型であればタイプライタとタイプリーダを作成する必要はありませんが、これをカスタマイズすることで独自のデータ型を扱うことができます。
通常、このようなコンテンツパイプラインの背景を詳細に理解していなくてもコンテンツを扱うことは可能ですが、独自のコンテンツを XNA Game Studio のビルドに統合したい場合、コンテンツパイプラインの各工程にある部品を拡張する必要があります。
8.1.3 標準インポータとプロセッサ
XNA Framework は、標準で画像ファイルやモデル、フォント、XML などを処理するためのインポータとプロセッサを提供しています。XNA Framework が標準で提供するコンテンツパイプラインに関連したクラスライブラリだけでも非常に規模の大きいものなので、そのすべてを本書内で説明することはできません。この場では、標準で提供されるインポータやプロセッサとその関係だけを紹介します。通常のゲーム開発で、これらの構造を理解する必要はありません。標準で提供されるインポータまたはプロセッサを利用する拡張ライブラリを作成するときに、MSDN などを参照して詳細を調べてください。
インポータとプロセッサは互いに依存せず、完全に独立した部品として動作します。インポータはソースアセットからデータを読み込み、適切なマネージ型に変換して結果を出力します。通常、この結果がプロセッサの入力に用いられます。表1は、XNA Framework が標準で提供するインポータのリストです。
インポータ名 | インポータ型 | 出力型 | ソースアセットの形式 |
---|---|---|---|
Autodest FBX - XNA Framework | FbxImporter | NodeContent | Autodesk FBX (.fbx) |
X File - XNA Framework | XImpoter | NodeContent | Direct X用Xファイル(.x) |
Effect - XNA Framework | EffectImpoter | EffectContent | エフェクトファイル(.fx) |
Texture - XNA Framework | TextureImpoter | TextureContent | サポートされる各種画像ファイル (.bmp、.dds、.dib、.hdr、.jpg、.pfm、.png、.ppm、.tga) |
Sprite Font Description - XNA Framework | FontDescriptionImpoter | FontDescription | フォント情報が書かれた.spritefont形式のファイル |
XML Content - XNA Framework | XmlImpoter | object | XML ファイル(.xml) |
インポータ名は XNA Game Studio のプロパティ上に表示されるインポータの名前です。インポータ型や出力型は、実際にライブラリで提供されるクラスです。これらのクラスは Microsoft.Xna.Framework.Content.Pipeline 名前空間以下に配置されています。
表2は、XNA Framework が標準で提供するプロセッサのリストです。
プロセッサ名 | プロセッサ型 | 入力型 | 出力型 |
---|---|---|---|
Model - XNA Framework | ModelProcessor | NodeContent | ModelContent |
Effect - XNA Framework | EffectProcessor | EffectContent | CompiledEffect |
Texture - XNA Framework | TextureProcessor | TextureContent | TextureContent |
Sprite Font Description - XNA Framework | FontDescriptionProcessor | FontDescription | SpriteFontContent |
Sprite Font Texture - XNA Framework | FontTextureProcessor | TextureContent | SpriteFontContent |
No Processing Required | PassThroughProcessor | object | object |
使用するインポータとプロセッサの組み合わせは自由ですが、インポータの出力型とプロセッサの入力型に互換性がなければいけません。
最も単純なインポータとプロセッサの関係はEffectImpoterとEffectProcessorのような1対1の関係となります。エフェクトファイルを読み込んだインポータが EffectContent 型のオブジェクトを出力し、これをプロセッサでコンパイルして CompiledEffect 型のオブジェクトを出力するという流れです。FbxImpoterとXImpoter のように、異なるインポータが同じ型を出力する場合もあります。これらのインポータに対しては、どちらの場合も ModelProcessor が共通して使われます。
PassThroughProcessor は、やや特殊なプロセッサでインポータから受け取ったデータをそのまま出力します。
8.1.4 コンテンツパイプラインの拡張
独自のインポータやプロセッサを作成するには、コンテンツパイプラインの拡張ライブラリ用のプロジェクトをゲームとは別に用意します。よって、一度作成したインポータやプロセッサを提供するライブラリは、他のゲームからも再利用できます。コンテンツパイプラインの拡張ライブラリは XNA Game Studio のビルド工程に組み込まれて実行されるものであり、ゲーム中に実行されるものではありません。よって、ゲームとは別のプロジェクトとして作成します。
コンテンツパイプラインの拡張ライブライ用プロジェクトを作成するには、メニューから「新しいプロジェクト」を選択して「新しいプロジェクト」ダイアログを表示してください。右上の「テンプレート」リストに表示されたている「Content Pipeline Extension Library (3.0)」を選択してプロジェクトを作成してください。
通常はゲーム用のプロジェクトと同じソリューションの中で開発またはテストを行います。拡張ライブラリの動作テストを行うためのゲーム用プロジェクトを、同じソリューションに追加してください。ゲームに追加したコンテンツを、独自に作成した拡張ライブラリを用いてビルドするには、ゲームの Content サブプロジェクトに参照を追加する必要があります。Content サブプロジェクトには、親のゲームプロジェクトとは別に参照設定があります。これを右クリックして「参照の追加」を選択してください。
「参照の追加」ダイアログが表示されるので、「プロジェクト」タブを選択してください。株のリスト内に拡張ライブラリのプロジェクトが表示されるので、これを選択して「OK」ボタンを押します。
図5のように、Contentサブプロジェクトの参照設定にコンテンツパイプラインの拡張ライブラリ用プロジェクトが追加されていれば成功です。これで、ゲームのプロジェクトから独自に作成したインポータやプロセッサが利用できます。
拡張ライブラリのプロジェクトは、ゲームとは異なりXbox 360やZuneのようなWindows以外のプラットフォームの制約を受けません。このプロジェクトで作成したプログラムはXNA Game Studioのビルド時に呼び出されるものであり、動作環境はWindows上の.NET Frameworkに限定されます。