sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

Unity TextMeshPro で画像 (sprite) つきテキストを表示する

Unity でテキストを表示する際は、UGUI だと Text ではなく TextMesh Pro を使ったほうがよいという記事を見つけたので、実際にやってみた記事です。

f:id:shikaku_sh:20200710120326p:plain:w500
こんな感じの「種類アイコン+アイテム名」をテキストで表現した

テキスト中に絵文字感覚の画像を入れたり、一部分だけのテキストは文字サイズや文字色を変えるといったことが可能だということがわかったので、たしかに TextMesh Pro を使ったほうがよさそうです。

コーディングだと「もしかして、デザインパターンを使ったほうがいいんじゃないか……?」みたいな、これが有用であるのは当然じゃないか、みたいな今更の話。

放置系ハクスラモンスターズは、テキストベースで展開するローグライクなゲームで、

f:id:shikaku_sh:20200710120145p:plain:h400
こんな感じの画像を含んだテキスト

みたいな表現で入手できるアイテムが気持ちよくて気に入っています。なので、これを目標にして試しにやってみた次第です。


TextMeshPro を初めて使うときのインポート

はじめて Hierarchy のシーン内に「Text - TextMesh Pro」を追加すると、下のようなテキストが書いてあるウィンドウが立ち上がりました。

f:id:shikaku_sh:20200710120633p:plain:w500
一瞬戸惑うけど、手助けしてくれるウィンドウだった

this appears to be the first time you access TextMesh Pro, aas such we need to add resources to your project that are essential for using TextMesh Pro.
There new resources will be placed at the root of your project in the "TextMesh Pro" folder.

TextMesh Pro を利用するために必要なリソースをプロジェクトに追加したいと言っているだけでした。「Import TMP Essentials」を選択して、TMP (TextMesh Pro) の必須コンポーネントをプロジェクトに追加します。


TextMeshPro で SDF データを作成する

SDF (Signed Distance Field) データは、日本語だと「符号付き距離場」というみたいです。ともかく、フォントのアトラスデータを SDF と呼ぶみたいです。通常の Text は、フォントだけで動作しますが、TextMeshPro は使用する文字を決めて、文字データを作成しないと(基本的には)描画できません。1

  • Assets に使用するフォントを追加
  • メニュー「Window>TextMesh Pro>Font Assets Creator」を選択
  • Font Assets Creator の設定
    • Source Font File にフォントを設定
    • Charactor Set を「Custom Charactors」に変更
      (日本語に対応させるため)
    • Render Mode は「SDFAA」
    • Get Kerning Parts は ON
    • Generate Font Atlas でアトラスデータを生成
    • Save でファイルを保存

とりあえず、日本語のひらがなやカタカナはまとめて登録してしまうと思いますので、基本的な文字をまとめておいたファイルはこちら。

f:id:shikaku_sh:20200710120917p:plain:h400
こんな感じで設定しました

この時点でテキストを描画できるようになります。

f:id:shikaku_sh:20200710121113p:plain:w400
こんな感じ

同じ文字を複数登録しようとしたとき

あまり詳しく調べていませんが、図のような動きをしたので、自動的に重複する文字は無視してくれている気がします。

f:id:shikaku_sh:20200710125813p:plain:h400
「ああああ」で登録すると「あ」の一文字だけ登録された


フォントの SDF データ(アトラスファイル)から Material Preset を生成する

テキストに縁取りなどのエフェクトを与える場合は Material Preset を生成して、そのプリセットに希望するエフェクトを設定する必要があります。

(操作の手順が独特なので)手順を忘れないように注意が必要です。

f:id:shikaku_sh:20200710125358p:plain:w500
図にするとこんな感じです

Material Preset ファイルが作成できたら、Face と Outline を 0.1 くらいにすると、縁取りができます。縁取りの精度とぼやけ・にじみは、フォント自体の Atlas Resolution のサイズが小さいとぼやけとにじみが大きくなります。

f:id:shikaku_sh:20200710125601p:plain:w500
大きくすると今度はファイルサイズが問題になります

単純な文字の縁取りだけなら Shader を TextMeshPro/Mobile/Distance Field に変更することで、Face と Outline だけ編集できます。

f:id:shikaku_sh:20200710125704p:plain:w500
縁取りだけならこれだけで十分

漢字を利用するとき

f:id:shikaku_sh:20200710125914p:plain:w400
漢字は特ににじみやすいです

漢字をたくさん利用する場合、登録する文字数を多くなるため、ファイルサイズを抑えるためにも粗いフォントを利用することになります。こういうときは、Font Fallback を利用して、フォントの SDF を分けて作成し、主となるフォントの Fallback Font Assets に SDF を登録します。

別のフォントで特定の文字を代替する

これも同じで Font Fallback を利用することで解決できます。数字なんかはフォントの好みが出やすいと思いますが、これは sprite 置き換え対応もあると思います。


タグで Sprite を表示する

TextMesh Pro の Rich Text Tags の書き方で、自分で作成した Sprite Atlas ファイルの画像を表示することができます。この記事でも、要点になる部分ですね。

<sprite="Sprite をまとめた Atlas ファイル名" index=番号>

Sprite ファイルは画像ファイルをインポートすればいいのですが、そこから Atlas ファイルを作成する方法は、デフォルトの方法ではむつかしいため、Assets Store から便利なツールを利用するのが一般的のようです。私は下記の Simple Sprite Packer を利用しました。

Simple Sprite Packer ツールは、Sprite ファイルを Atlas ファイルに変換するためのツールです。さっそく Import します。

f:id:shikaku_sh:20200710130014p:plain
Import するときのウィンドウ

Project ウィンドウから、画像を管理するフォルダーに Sprite Packer を追加します。Sprite Packer を開いて、Atlas 化する画像ファイルを(緑色の領域に)ドラッグ&ドロップします。

もともと1枚の Sprite データに複数のイメージを格納してある場合は、Sprite Mode を Multiple にして分割したあと、分割した Sprite を Atlas ファイルにしてください。

「Rebuild Atlas」を選択して、Atlas 化した画像ファイルが完成。

f:id:shikaku_sh:20200710130326p:plain:w500
操作の流れ

ドット絵のようにアンチエイリアスを嫌う画像タイプの場合は、Atlas ファイルも Sprite ファイル同様に Filter Mode を Point (no filter) にするといった設定をしてください。

f:id:shikaku_sh:20200710130528p:plain:h400
アンチエイリアス対策

Atlas 化したファイルを最後に SDF ファイルにするため Project ウィンドウから Atlas ファイルを右クリックして、Create>TextMeshPro>Sprite Asset を選択します。

f:id:shikaku_sh:20200710130105p:plain:w500
ここの操作を忘れやすい気がします

f:id:shikaku_sh:20200710130348p:plain
最終的にはフォントの SDF ファイルと同じアイコン

完成した SDF ファイルは TextMesh Pro>Resources>Sprite Assets に追加します。すでにサンプルとして、EmojiOne という SDF ファイルがあるフォルダーです。

この状態で Text - TextMesh Pro のテキストを編集します。

f:id:shikaku_sh:20200710130632g:plain:w600
完成

いい感じですね。これだとテキストデータの編集をするだけで、放置系ハクスラモンスターズのアイテムっぽいテキストを用意することができます。

あとは、スクロールビューと組み合わせると、いい感じになるんじゃないでしょうかね。

Sprite の表示位置がずれるとき

最終形の SDF ファイルを選択して、Sprite Glyph Table の「BX」「BY」を編集します。

すべての画像位置の場合は、一番したにある「OX」「OY」を編集します。

f:id:shikaku_sh:20200710130909p:plain
表示位置の調整

パフォーマンスについて

この記事ではパフォーマンスについてあまり触れていませんが、「Unity Blog - Unity 2018 で TextMesh Pro を最大限に活用しよう」では次のように説明されています。

パフォーマンスに関しては、上述のとおり TextMesh Pro とデフォルト目テキストはあまり変わりません。

なので、凝ったことをしない場合は特に使ってみて損がなさそうです。パフォーマンスを気にする場合は次の記事なんかもよさそうです。


サンプル

テストプログラムは GitHub に「unity-textmeshpro-practice」を公開しています。

f:id:shikaku_sh:20200710133824p:plain:w500
こんな感じ

参考

Unityの教科書 Unity2020完全対応版 (2D&3Dスマートフォンゲーム入門講座)

Unityの教科書 Unity2020完全対応版 (2D&3Dスマートフォンゲーム入門講座)

  • 作者:北村愛実
  • 発売日: 2020/08/07
  • メディア: 単行本(ソフトカバー)

Effective C# 6.0/7.0

Effective C# 6.0/7.0


  1. SDF データの Inspector より「Generation Settings>Atlas Population Mode」を dynamic にすることで、動的にデータを作成することができるようになりました。ただ、これも実行や保存ごとに Generation Font Atlas を実行しているような動きをするので、手間ですが手動でやるほうが適切だと思っています。