【Unity】ダイナミックフォントの知っておくべき内部挙動

Unityではフォントファイルを指定することで好きなフォントを使えます。
便利な機能ですが、内部挙動を知らないとパフォーマンスに悪影響を及ぼしてしまうことがあるので簡単にまとめます。

テキストを表示するまでの流れ

たとえばText Meshを使ってテキストを表示する流れは次のようになります。

まずText Meshにテキストを入力します。
f:id:halya_11:20180603165456p:plain

つぎに、入力された文字だけを含むフォントアトラスというテクスチャが内部的に作られます。
f:id:halya_11:20180603172703p:plain

また、文字の大きさに見合ったメッシュが文字の数だけ作られます。 f:id:halya_11:20180603170417p:plain

そしてUVを指定してフォントアトラスをサンプリングすることで、文字がメッシュにレンダリングされます。
f:id:halya_11:20180603170054p:plain

フォントアトラスの挙動

前節で説明したフォントアトラスは次のような特徴を持っています。

まず、Text Meshを2つ用意して異なるフォントを指定した場合、フォントアトラスは2つになります。
f:id:halya_11:20180603172736p:plain

つぎに、フォントは同じでフォントサイズを変えた場合、
1枚のフォントアトラスにサイズの違うテキストが追加されます。
f:id:halya_11:20180603171455p:plain

スタイルだけを変えた場合も同様です。
f:id:halya_11:20180603171644p:plain

つまり、サイズやスタイルの種類が多ければ多いほどフォントアトラスは肥大化します。
f:id:halya_11:20180603172047p:plain

また、動的にいろんな文字を使う場合にもどんどんフォントアトラスが大きくなっていきます。サイズが大きいならなおさらです。
f:id:halya_11:20180603172419p:plain

フォントアトラスはすべての文字が収まる最小サイズで作られますが、それに収まらなくなった時にはテクスチャサイズを大きくして作り直します。
このとき、使われなくなった文字があればアトラスから消えます。

フォントアトラスは上記のような仕様なので、次のようなケースではパフォーマンスに注意が必要そうです。

  • フォントアトラスへの文字の追加が多くなる場合
  • フォントアトラスが大きくなりすぎる場合
  • フォントアトラスのサイズが頻繁に変更される場合

パフォーマンス上の注意点は下記の記事が詳しいです。

unity3d.com

内部挙動の確認

Text Meshなどの内部挙動はなかなか見づらいですが、テクスチャアトラスは結局マテリアルに渡されるのでマテリアルの情報が見れればOKです。
下記のようにマテリアルの複製を作ればInspectorに表示されるので、確認したいだけならこれで十分かと思います。

using UnityEngine;

public class FontDebug : MonoBehaviour {

    private Material _material;

    private void Awake () {
        _material = GetComponent<MeshRenderer>().material;
    }

    [ContextMenu("Log Texture Size")]
    private void LogTextureSize(){
        var texture = _material.mainTexture;
        Debug.Log(texture.name + " Size: (" + texture.width + ", " + texture.height + ")");
    }
}

このコンポーネントをText MeshのアタッチされているオブジェクトにアタッチすればテクスチャがInspectorから見れます。
ついでにテクスチャサイズは右クリックメニューから確認できるようにしています。

自分でメッシュを作る

余談ですが、メッシュから自作する方法がFont.RequestCharactersInTexture()のマニュアルに載っていたのでリンクしておきます。

docs.unity3d.com

参考

unity3d.com

docs.unity3d.com