カスタムコンテンツプロセッサーを利用した高度な日本語表示を行う
日本語表示について
MonoGame においてのテキスト描画は XNA と同様に SpriteFont を使うことになります。SpriteFont については XNA と同じなので「英数字を表示させる」や「フォントスタイルの詳細」を参照してください。
SpriteFont を使う場合は事前に使う文字を指定しておく必要があります。英数字記号だけであればたかだか100文字程度なので文字指定やビルド時間もほとんどコストなく行えるのですが、日本語となると数千文字となってしまうため、ビルド時間がとてつもなく長くなってしまいます。使う文字だけ指定すればある程度ビルド時間は短縮できますが、逆に使う文字を指定するのが面倒であり、使う文字に変更があった場合はさらに面倒になります。
この問題に対し、「ひにけにGD」さんのサイトでは XNA においての日本語の描画をよりスムーズに行えるようにカスタマイズされています(ちなみにサイト運営されている Yuichi Ito - MSFT 氏は XNA Framework 開発者の一人です)。これを利用すると使う文字の指定が簡単になり、ビルド時間の短縮、文字の装飾などができるようになります。詳しくはリンク先をご覧ください。
しかし、ページ先で紹介されている「WPF フォントプロセッサー」は XNA 用であるため、MonoGame ではそのまま使うことはできません。ですのでこれを MonoGame に移植してみたいと思います。
WPF フォントプロセッサーのダウンロード
以下のサイトを開きます。
下の方にスクロールするとリンクが2つあり、上のリンクをクリックするとソートコードが含まれたプロジェクトがダウンロードできます。下の方は DLL だけですのでダウンロードしなくてもいいです。
ダウンロードしたファイルは中身を取り出せるように展開しておいてください。
WPF フォントプロセッサーのプロジェクト作成
今回作成する「WPF フォントプロセッサー」の DLL は「Any CPU」で動作するものを作成したいのですが、XNA Framework の「Content Pipeline Extension Library」でプロジェクトを作成するとなぜか x86 でしか作成できないので、ここでは通常のクラス ライブラリから作成します。
プロジェクトを作成したら「Class1.cs」はいらないので削除します。
続いて参照の追加を行います。
WPF でテキストを描画するので、WPF 関連の参照が必要になります。まずは「フレームワーク」から「PresentationCore」にチェックを入れます。
続いて「WindowsBase」にチェックを入れます。ここでいったん OK ボタンを押して確定し、再度参照マネージャーを開いてください。
左の「参照」を選択して、下の「参照」ボタンをクリックしてください。
以下のフォルダパスを開きます。
- C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\
そこから以下の2つの DLL を追加します。
- MonoGame.Framework.dll
- MonoGame.Framework.Content.Pipeline.dll
チェックされていることを確認し「OK」ボタンをクリックします。
追加された参照を確認します。
続いてダウンロードしたプロジェクトから「WpfFontPipeline」フォルダにあるソースコードを現在編集しているプロジェクトに追加します。
追加した状態です。
ビルド構成が「Release」「Any CPU」になっていることを確認します。
ビルドを行い、正常にビルドされたか確認します。
DLL が作成されていることを確認します。
ゲームプロジェクトの作成
MonoGame のプロジェクトを作成します。プラットフォームはなんでもかまいません。
先ほど作成した DLL を Content フォルダに入れておきます。DLL の場所はどこでも構わないのですが、その場合相対、または絶対パスが必要になるので、とりあえず今回はここにおきます。
Content.mgcb を開き、「Content」を選択している状態で「References」を開きます。
※「Content.mgcb」をダブルクリックしても開かない場合は、スタートメニューから「MonoGame Plipeline」を起動してください。
テキストボックスに先ほど作成した DLL のファイル名、または Content.mgcb からの相対パス、または絶対パスを入力します。
設定後はまだ DLL が反映されないので、いったんプロジェクトを保存、MonoGame Pipeline を終了し、再度開いてください。
スプライトフォントを作成します。メニューから「Edit」→「Add」→「New Item」を選択します。
項目の中から「SpriteFont Description」を選択して追加します。(ちなみに SpriteFont を追加した後、実行時に見やすいように SpriteFont のファイルを開いてフォント名とサイズを変更しています)
追加した SpriteFont を選択すると、Processor から「WPF フォントプロセッサー」が選択できるようになっていることがわかります。
各パラメータが設定できるので、とりあえず今回は図のように設定してみました。残念ながら現バージョンの MonoGame Pipeline では色変更はできません。
ビルドしてみます。JIS第2水準まで含めたので 6860 文字がビルドされました。それでも時間は 9 秒ほどなのでかなり高速化されていることがわかります。
さて、この SpriteFont を使用して描画するのですが、コードの方は XNA とまったく同じです。「英数字を表示させる」で紹介しているコードをそのまま使えばテキストを描画できます。もちろん日本語も可能です。
一応追加したコードだけ載せておきたいと思います。
フィールドの定義部分です。「SpriteFont」を追加しています。
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont font;
LoadContent メソッド内でフォントデータを読み込み、作成しています。
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
// フォントデータの読み込み
font = Content.Load<SpriteFont>("Font");
}
Draw メソッドで日本語を指定して描画しています。
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.DrawString(font, "真・簡単(かもしれない)日本語表示",
new Vector2(50, 50), Color.White);
spriteBatch.DrawString(font, @"・OpenTypeフォント対応
・処理速度の高速化
・JIS漢字追加機能
・文字装飾",
new Vector2(50, 150), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
実行するとテキストが描画されます。少しわかりづらいですが、文字に枠線がついているのと、中で青のグラデーションがかかっています。
こんな感じで日本語の描画が楽になり、装飾付きの文字も描画できるようになりました。
最後に文字の装飾の色について、MonoGame Pipeline 上では変更できませんが、ファイルを直接開いて変更できるのでその方法を説明します。
プロジェクトをいったん保存して閉じたら「.mgcb」ファイルをテキストファイルで開きます。
下にスクロールすると対象パラメータに色情報があるのでそこを直接編集してください。
テキストを保存したら再度 MonoGame Pipeline を開きビルドします。実行すると色が変わっていることがわかると思います。