コンテンツパイプラインについて


サンプルのコンテンツパイプラインを自作のプログラムに流用する際は番号どおりに組み込んで行くと比較的楽に実装できます


Content Pipeline のコードはビルドプロセスの一環として実行されます。ゲーム本体のランタイムでは実行されません
XNAではゲームに必要な音、映像、ゲーム制御用のデータ(XML等)に関してContentManagerクラスを利用してゲームに組み込む
入力にはインポーター、出力にはプロセッサが使用される。画像の場合、例えばjpgとしてインポータでLoad入力された画像データは
コンパイル時、プロセッサを介してTexture2Dアセットとしてゲーム用データに変換されXNBファイルとして出力される
(デバッグビルドの場合、bin\x86\Debug\ContentフォルダのXNBという拡張子の付いたファイル)
登録したファイルは「Content」フォルダに収められ「Content.contentproj」というXMLファイルで管理される。

  • Content Pipeline のコードは、ビルド プロセスの一環として実行されます。ゲーム本体のランタイムでは実行されません。設定データをビルドできるようにするには、このデータをビルドしている間、設定クラスの定義が利用できる必要があります。ただし、データをビルドする時点では、ゲーム自体はまだビルドされていません。そのため、設定データがゲームの内部で定義されている場合、解決不可能な循環した依存関係が存在することになります。
  • Content Pipeline のコードはビルドの一環として実行されるので、ゲーム自体が Xbox 360 をターゲットにしていても、必ず Windows 上で実行する必要があります。つまり、Xbox ゲームをビルドしているときは、Content Pipeline のデータ ビルド中に使用される Windows バージョンと、実行時にゲーム自体が使用できる Xbox バージョンの、2 つのバージョンの設定クラスが存在している必要があります。
  • 設定クラスをゲームとは別のアセンブリに配置することは、これらの両方の要件を満たすための優れた方法です(ゲーム本体とは別のプロジェクトにランタイムクラスを収めプロジェクトのアセンブリ名をゲーム本体とは別のものにすると分離した事になる)この分離したアセンブリはパイプライン側からも利用する。つまるところ疎結合されたようなニュアンスになる。

別のアセンブリに配置するにはソリューションエクスプローラーで新たなプロジェクトを追加(ソリューション>追加>新しいプロジェクト)
ゲーム本体のプロジェクトの参照設定に「参照の追加」をして「プロジェクト」から該当するプロジェクトを選択します。
(プロジェクトに含まれるソースの名前空間は合わせておくか、using等でアクセス可能にしておく事)

ContentManager はインスタンスを作成しても利用できるが Game クラスが提供する Content プロパティを利用することも出来る。
好みで利用すると良い。その際は Content.RootDirectory プロパティでコンテンツフォルダを指定することを忘れずに。


クラスや構造体のpublicなメンバーをXMLでシリアライズしてファイル出力、XNAのコンテンツパイプラインでローディングし実装する具体的な手順


<条件>対象のクラスは別のアセンブリで作成する事!
1.ソリューションに新しいプロジェクト(DLLやアプリでないもの、クラスが望ましい)を追加しcsファイル内の名前空間をXNAのソースコードに合わせる
2.XNAのソースがあるプロジェクトの参照設定に新しく加えたプロジェクトを登録。そしてコンテンツである「~~Content(Content)」プロジェクトの参照設定にも新しいプロジェクトを登録する(つまり、ふたつの登録が必要)
3.新しく加えたプロジェクト内のcsファイルに出力したいオブジェクトを作成する。public修飾子のメンバーがプロパティも含め出力される。メソッドやコンストラクタは無視される(string、int等のほかにList<T>等も正常に出力される)
3.もし必要であればサンプル読み込み用のXMLを出力するコンソールアプリのプロジェクトを作成する。以下のコードはその例
using System;
using System.Collections.Generic;
using System.Xml;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate;

namespace XMLTest
{
   class Program
   {
       static void Main(string[] args)
       {
          //保存したいクラス
           People people = new People("Japan", "Osaka");

           //XML出力
           XmlWriterSettings setting = new XmlWriterSettings();
           setting.Indent = true;
           using (XmlWriter writter =  XmlWriter.Create("test.xml", setting))
           {
               IntermediateSerializer.Serialize<People>(writter, people, null);
           }
       }
   }
}
Microsoft.Xna.Framework.Content.Pipeline.Serialization.Intermediate を参照するには
参照設定に.NETの Microsoft.Xna.Framework.Content.Pipeline を加える必要がある。既定のプロジェクトの場合フレームワークは
「.NET FrameWork4 client profile」になっているのでこれをプロジェクトのプロパティから「.NET FrameWork4」に変更してから参照設定を行う(こうしないと.NETのメニュー内に該当項目が表示されない)
コンソールアプリとXNAのゲームアプリの二つが同じソリューション内にある筈なのでソリューションのプロパティを利用してマルチスタートアッププロジェクトとして該当のふたつのプロジェクトを選択しビルドして実行すると良い

4.XNAのソースでローディングしてみる。読み込みたいファイル test.xml をコンテンツフォルダ(「~~Content(Content)」プロジェクト)内にコピーしてXNAソースのInitialize()メソッド内などで以下コードのように読み込む
ちなみにファイル名の拡張子は必要ない。XNAフレームワークはXMLファイルを読み込みクラスの各メンバーに適切なパラメーターをセットしてくれる機能を標準で持っている
       protected override void Initialize()
       {
           // TODO: ここに初期化ロジックを追加します。
           People people;
           people = Content.Load<People>("test");
           base.Initialize();
       }

  • ContentSerializer について
XNAでは属性を使用してコンテンツパイプラインで扱う値、メンバーやプロパティを指定する
「ContentSerializer 属性」はXNAフレームワーク自身がサポートしている属性
<コンテンツシリアライザ属性の種類>
ContentSerializer シリアル化に含める必要があることを示す
ContentSerializerIgnore シリアル化されないようにするためにマークする属性
以下は属性を使ってシリアライズが不要な値を指定している。基本的に属性定義のすぐ後にあるコードが対象となる
[ContentSerializerIgnore]
Texture2D texture = null;
最終更新:2012年07月31日 02:50
添付ファイル