Edited at
UnityDay 6

NGUIでのA8フォントの使い方

More than 5 years have passed since last update.

A8とは「アルファ8bitのみの情報を持ったテクスチャ形式」のこと。フォントに使うテクスチャにはRGB値がいらないことが殆どなので、A8にしちゃえばサイズの削減になるという手法の紹介。

NGUIで日本語など文字数の多いフォントを使う場合、テクスチャサイズの肥大化に悩まされるかと思います。

ただ、既に対策は用意されていて、PackedFontというやり方があります。

これは、ARGB4チャンネルをA8×4チャンネルとして扱うという方法です。

紹介の記事はUnityの伊藤さんのブログに。http://warapuri.tumblr.com/post/23352109465/ngui

詳細の動画はここで http://www.youtube.com/watch?v=dY6jQ7d2ius

ただこれを使うと、どうも文字の縁取りや影(OutlineやShadow)には非対応になってしまうらしい。

NGUIのサポートフォーラムではソースコードの改変での解決方法が載ってますが、どうも公式で対応する気配がない模様。

http://www.tasharen.com/forum/index.php?topic=757.0

そこで、需要があるかわからないですが、もうひとつのやり方の「NGUIでのA8フォント」のやり方をまとめました。

必要なのは下記2点で、ソースコードの改変はしなくてOK

1.A8用のフォントテクスチャの作成

2.A8用の描画シェーダを適用

●A8用のフォントテクスチャの作成

・pngファイル等の作成。

通常の作り方と一緒。

手順は「強火で進め」さんの解説がわかりやすいので紹介。

http://d.hatena.ne.jp/nakamura001/20120910/1347241168

ExportOptionで、「White with Alpha」を選ぶのがコツ。

・テクスチャのインポート設定。

インポート設定は以下のように。上記、Unity伊藤さんのブログの画像を参考に

http://media.tumblr.com/tumblr_m49yqyPTkh1rp3idm.jpg

●A8用の描画シェーダを適用

・簡易的なシェーダ

簡単にやるなら、シェーダは「GUI>Text Sahder」でOK。(Unity4.0で動作確認)

シェーダの中身はこんな感じになってるようだ。

http://wiki.unity3d.com/index.php?title=3DText

・A8用の描画シェーダの作成

さてここからがちょっと問題。

PanelのClipping機能を使う場合、A8用のシェーダを作成しないといけなくなる。

とはいっても、既存のNGUIのシェーダをコピペして少し手を加えるだけでOK。

・Unlit - A8Font.shaderを作成

まずは「GUI>Text Sahder」の代わりにNGUIの「Unlit - Transparent Colored.shader」をコピペして、Unlit - A8Font.shaderを作る。

色の計算部分だけ以下のように書き換えること。

        SetTexture [_MainTex] {

constantColor (1, 1, 1, 1)
Combine constant * Primary, texture * Primary
}

なにをやってるかというと、テクスチャのrgb値を(1,1,1)つまり白色に固定している。

A8のテクスチャには色の情報が0,0,0として扱わてしまい、そのままだと色をつけられなくなってしまうので、白に固定してやる必要がある。

・シェーダをマテリアルに適用

シェーダができたら、マテリアルにはこちらのシェーダをつける。

・Clipping用のシェーダを作成

さて、肝心のClipping用のシェーダ。

Unlit - Transparent Colored (SoftClip)などのシェーダをコピペして、

Unlit - A8Font (SoftClip).shaderなどを作る。

ここでの注意点。Clip系のシェーダは命名規則が決まっていて、「基本シェーダ名+ (SoftClip)」となっている。

NGUIはスクリプト上で、シェーダの名前を作成して動的にクリップ用のシェーダに切り替えるということをやっているので、命名規則が狂うとクリップ用のシェーダが適用されなくなる。

SoftClipのシェーダは上記SetTexture部分の改変のほかに、

フラグメント処理部分(fixed4 frag)のreturnの一行だけ以下のように修正すること。

            return half4(IN.color.rgb, col.a*IN.color.a);

自分はHardClipやAlphaClipを使っていないので作っていないですが、必要であればHardClipやAlphaClipようのA8シェーダも用意すること。

(ちなみにHardClipは、以前一部のAndroidでフリーズしたので使わないようにしてる)

これでサイズを1/4に圧縮して、縁取りや影がつけられるフォントが描画できます。

実際に書くコードの量は殆どないですが、けっこう手順がややこしい。

GreeのLWFプラグインの中には、NGUI用のシステムフォントのスクリプトもあるそうなので、そっちのほうが確実かもしれないです。

個人的には、Unity4.xの新GUIシステムに期待。この手の微妙な面倒くささが早くなくなるといいな。