WisdomSoft - for your serial experiences.

8.3 プロセッサ

プロセッサは入力されたデータをゲーム用に変換してタイプライタに渡します。ビルド時にパラメータや対象プラットフォームに応じた最適化を行い、出力に渡します。

8.3.1 データの入出力

プロセッサの役割は、インポータが返したデータを受け取りゲームに最適化するなどの変換処理を行って結果を出力することです。プロセッサによって、同一のソースアセットから異なる複数の結果を得るなどの柔軟な管理が可能になります。

新しいプロセッサを開発するには Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor クラスを継承する新しいクラスを作成します。

Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor クラス
public abstract class ContentProcessor<TInput,TOutput> : IContentProcessor

TInput 型パラメータにはプロセッサに入力する型を、TOutput 型パラメータにはプロセッサが出力する型を指定します。

ContentProcessor クラスは抽象クラスであり、このクラスを継承するには Process() メソッドを実装しなければなりません。このメソッドにインポータが出力したデータが入力されるので、適切な変換を行い結果を出力します。インポータと同じように、このメソッドはビルド時に自動的に呼び出されます。

ContentProcessor クラス Process() メソッド
public abstract TOutput Process (
         TInput input,
         ContentProcessorContext context
)

input パラメータに、このプロセッサが処理するべきデータが渡されます。context パラメータは、現在のプロセッサ処理の情報を提供する Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext クラスのオブジェクトが渡されます。

Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext クラス
public sealed class ContentProcessorContext

インポータの場合と同じように、このクラスの Logger プロパティから ContentBuildLogger オブジェクトを取得できます。ここから、プロセッサの状態などをメッセージとして出力できます。

ContentProcessorContext クラス Logger プロパティ
public ContentBuildLogger Logger { get; }

また、TargetPlatform プロパティから現在のビルドが対象としているプラットフォームを取得できます。このプロパティを調べることで、Windows 用のプロジェクトと Xbox 360 用のプロジェクトで異なる変換を行い、対象のプラットフォームに最適化したデータを出力できます。

ContentProcessorContext クラス TargetPlatform プロパティ
public TargetPlatform TargetPlatform { get; }

このプロパティから、現在のビルドの対象となるプラットフォームを表すTargetPlatform列挙型の値を得られます。

最後に、新しく作成した ContentProcessor クラスを継承するカスタムクラスに対して ContentProcessorAttribute クラスを属性として設定します。この属性は、対象のクラスがプロセッサの実装であることを表し、表示用のプロセッサ名などを提供します。

Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorAttribute クラス
public class ContentProcessorAttribute : Attribute

このクラスのコンストラクタは、パラメータを受け取りません。

プロセッサの表示名は DisplayName プロパティで表されます。

ContentProcessorAttribute クラス DisplayName プロパティ
public virtual string DisplayName { get; set; }

このプロパティは、開発環境に表示するプロセッサの名前を表します。インポータに指定した ContentImporterAttribute クラスの DisplayName プロパティと同じ役割です。

コード1 ContentPipelineExtension TextProcessor.cs
using Microsoft.Xna.Framework.Content.Pipeline;

[ContentProcessor(DisplayName="Text Processor")]
public class TextProcessor : ContentProcessor<string, string>
{
    public override string Process(string input, ContentProcessorContext context)
    {
        string result = input.ToUpper();
        context.Logger.LogMessage(
            "プロセッサを開始します\n" +
            "\tプロセッサの入力文字列=" + input + "\n" +
            "\tプロセッサの出力文字列=" + result
        );
        return result;
    }
}
実行結果
コード1 実行結果

コード1の ContentPipelineExtension プロジェクトにある TextProcessor クラスが、ContentProcessor クラスを継承したテキスト処理を行うプロセッサです。このプロセッサは文字列型のデータを受け取り、変換処理を行って結果を返します。出力も文字列型ですが、入力された文字列を大文字に変換して結果を返しています。

インポータやゲームのプログラムは「インポータ」で解説したコードと基本的に同じです。ゲームの Content サブプロジェクトに追加したテキストファイルの「Content Impoter」プロパティを Text Impoter に設定し、「Content Processor」プロパティを Text Processor に設定してください。これで、インポータが返した文字列をプロセッサが受け取り、変換した結果が出力されます。実行結果を見れば、テキストファイルのアルファベットが大文字に変換されていることが確認できます。

8.3.2 パラメータ

プロセッサは、開発環境からパラメータを受け取ることができます。パラメータを利用することで、プロセッサが処理するデータのオプション情報に従って実行するプログラムを切り替えたり、変換の参考値とすることができます。パラメータを使えば、ちょっとした処理の違いで異なるプロセッサをいくつも用意する必要がなくなります。

例えば、前述したコード1の文字列を大文字に変換するプロセッサを改良し、パラメータから大文字に変換するか、小文字に変換するか、または変換しないかを表す値を受け取るといったことが可能です。上手にパラメータを活用することで、多くのゲームで汎用的に活用できるプロセッサを開発できます。

プロセッサがパラメータを受け取る方法は、書き込み可能なプロパティを公開するだけです。プロパティが公開されているプロセッサを選択すると「プロパティ」ウィンドウのプロセッサの項目が展開できるようになり、プロパティ名が表示されます。ただし、パラメータとして利用するプロパティの型は基本データ型と文字列、列挙型、Vector2構造体、Vector3構造体、Vector4構造体、そしてColor構造体のいずれかに限定されます。これ以外の型のプロパティは無視され、パラメータとしては利用できません。

コード2 ContentPipelineExtension TextProcessor.cs
using Microsoft.Xna.Framework.Content.Pipeline;

public enum TextOperation
{
    ToUpper, ToLower, None
}

[ContentProcessor(DisplayName = "Text Processor")]
public class TextProcessor : ContentProcessor<string, string>
{
    private TextOperation textOperation;
    public TextOperation TextOperation
    {
        get { return textOperation; }
        set { textOperation = value; }
    }

    public override string Process(string input, ContentProcessorContext context)
    {
        if (textOperation == TextOperation.ToUpper)
            return input.ToUpper();
        else if (textOperation == TextOperation.ToLower)
            return input.ToLower();
        else return input;
    }
}

コード2は、コード1の TextProcessor クラスを改良したもので、文字列の変換をどのように行うかを表す TextOperation プロパティを追加しています。このプロパティには、文字列の変換方法を表す TextOperation 列挙型の値を設定します。

ゲーム用のプロジェクトにある Content サブプロジェクトにテキストファイルを追加し、「プロパティ」ウィンドウの「Content Processor」プロパティで Text Processor を選択すると項目を展開してパラメータを入力できることが確認できます。

図1 プロセッサのパラメータを選択
図1 プロセッサのパラメータを選択

項目を展開すると「TextOperation」プロパティが表示されるので、列挙型のメンバをリストから選択してください。ToUpper メンバを選択すると大文字に、ToLower メンバを選択すると小文字に変換されます。None メンバを選択した場合は変換されません。

「プロパティ」ウィンドウ上に表示されるプロパティ名やプロパティの説明、ツール上のデフォルト値などを設定することもできます。これらの設定は XNA Framework の機能ではなく、 System.ComponentModel 名前空間を使います。表示するプロパティ名は DisplayNameAttribute クラス、プロパティの説明は DescriptionAttribute クラス、デフォルトの値は DefaultValueAttribut クラスをプロパティの属性として設定します。

[DisplayName("Text Operation")]
[Description("入力された文字列に対する操作方法を指定します。")]
[DefaultValue(TextOperation.None)]
public TextOperation TextOperation ...

上の TextOperation プロパティのように、プロセッサのパラメータとなるプロパティに属性を設定すると「プロパティ」ウィンドウに表示されるプロパティ名や説明を任意のテキストに変更できます。

図2 プロパティ名、説明、デフォルトの値の変更
図2 プロパティ名、説明、デフォルトの値の変更

デフォルトの値はツール上の参考として用いられるもので、プログラムの動作に影響を与えるものではありません。