unity 2018.LTS、unity 2019.LTS ではほぼ標準とも言うべき Text Mesh Pro で日本語フォントを作成するまでの手順を紹介します。
なお、日本語フォントとしましたが、英語や数字だけでも手軽に高品質の表示が可能なので、
- フォントは重いし、信用ならない
- スコア表示やタイトルセレクトなど、面倒だけど毎回絵を作っている
こんな方も、試しに使ってみることをお勧めします。
下準備
Open Type Font (拡張子 otf)、もしくは True Type Font (拡張子 ttf) を用意してください。
とりあえず…であれば Noto Sans / Noto Serif などはライセンス緩めで、良さそうです。
フォントライセンスには注意しましょう。
フリーではなかったり、GPL ライセンスだったりで市販の(しかも結構著名な)ゲームですら過去大きな問題になったこともあります。
Font Asset Creator でフォントを作成
Window - TextMeshPro - Font Asset Creator
Source Font File
作成したい otf、または ttf ファイルをドラッグします。
ドラッグする otf / ttf ファイルは Assets フォルダに含めないとドラッグできません。
Sampling Point Size
Custom Size で、大きさは 20~45 くらいにしておくと普通の文字であれば充分な品質が得られます。
数字が大きいほど、大サイズのフォントでも綺麗に表示されますが、その分ファイルサイズも巨大化します。
Padding
デフォルトのまま(4)
Packing Method
Fast .. パッキング時間が早い、サイズが少し大きい
Optimum .. パッキング時間が激遅、サイズが少し小さい
日本語のような大量の文字数の場合、Optimum を設定するとパッキングに数時間かかる割にたいしてサイズが小さくならないので、Fast でいいと思います。
Atlas Resolution
4096 x 4096 がファイルサイズ的にも適当だと思いますが、お好みで。
ただし、Sampling Point Size が大きすぎたり、Character Set が多すぎると 4096 x 4096 に収まらないかもしれません。その場合は Sampling Point Size を小さくするなどして対応します。
Character Set
Characters from file を選択し、Character file は次の項にあるファイルをプロジェクトに含め、ドラッグしてください。
Render Mode
SDFAA を選択しておけば大体問題ありません。
最初に選択されている SMOOTH_HINTED はパッキングが高速ですが解像度が粗く、シェーダーの Outline や Underlay が使えないので注意してください。
Generate Font Atlas
このボタンを押すと、パッキングフォントを作成します。
完了したら、Save / Save as... で作成したフォントを保存します。
保存した後、otf /ttf ファイル、Character Set のテキストは不要になります。
プロジェクトから消しても大丈夫です。
Character Set の文字列
日本語の文字列を抽出したテキストを公開しています。
半角のみ (jp_hankkaku) / 半角+ひらがなまで (jp_hira) / JIS第1水準まで (jp_jis1) / JIS第2水準まで (jp_jis2) の4パターン用意しました。
配置してみる
ヒエラルキーで 右クリック > UI > Text - Text Mesh Pro を選択
Font Asset に Font Asset Creator で作成したファイルを指定します 。
とりあえず一行表示でよければ Wrapping を Disabled にします。
Width、Height、Font Size、Alignment などをお好みに調整します。
文字をクリックされたくない場合は、Extra Settings - Raycast Target のチェックを外します。
便利な Auto Size
横一行に入る文字数がわからず、表示エリアをはみ出してしまうことがよくあります。
AutoSize にチェックを入れるとこのように、黄色の枠に収まるよう自動的にフォントサイズが変化します。
- 黄色い枠は Width, Height で調整します
- Auto Size Options の Min が最小フォントサイズ、Max が最大フォントサイズ
フォントに影や境界線をつける
通常のテキストと異なり、軽量、かつ高品質な効果をかける事ができます。
- シェーダーの Face - Dilate、Outline - Thickness を同じ値で上げていくと境界線
境界線のある状態で Face - Softness を上げていくと境界線がぼやける - シェーダーの Underlay にチェックを入れて、Offset X を 1、Offset Y を -1 にすると文字の右下に影
影のある状態で Underlay - Softness を上げると影がぼやける
ただし、作成したフォントの Render Mode が SMOOTH(_HINTED) の場合適用されませんので注意してください。
全ての文字が同じ効果になってしまう問題
上の例のように別々の効果がかかったテキストを目指したのに、全て最後に設定した効果になってしまったかもしれません。
フォント効果の内容は、Object Component ではなく Material が記憶しています。
初期状態では、1フォント1マテリアルのため、テキストが5つあっても、全て1つのマテリアルを参照しているので、全部同じ効果になってしまいます。
テキストごとに別フォント(表示するフォントは同じでも…)を作って割り当てる、とすることもできますが、容量やロード時間が爆発的に増えるためお勧めできません。
それより1フォント複数マテリアルとし、それぞれのテキストにマテリアルを割り当てれば狙った通り別々の効果を割り当てることができます。
マテリアルを複数にする方法
フォントの中にある ???? Material を選択します。
Inspector の右上、歯車アイコンをクリック > Create Material Preset
新しく作成されたマテリアルは、分かりやすいように名前を変更してください。
テキストオブジェクトを選択し、Inspector の Material Preset を作成したものに変更します。
こうすることで、マテリアルごとに変化をつけることができます。
テキストにタグを書く事で、表示にバリエーションをもたせる
かなり色々なことができる!
参考サイト様は英語での記述ですが、パッと見でわかるようになっていて、便利です。
GCスパイクしまくりの適当コーディングですが、こんな事もできます。
以下のコードを TextMeshPro と同じ GameObject にアタッチする事で、テキストが自動的に波打ちます。
using TMPro; using UnityEngine; public class TextTest : MonoBehaviour { public TextMeshProUGUI text; string plaintext; float time; // Start is called before the first frame update void Start() { plaintext = text.text; time = 0; } // Update is called once per frame void Update() { time += Time.deltaTime; while (time > 1.0f) time -= 1.0f; if (time < 0) time = 0; float t = time; string txt = ""; for (int i = 0; i < plaintext.Length; i++) { float val = Mathf.Sin(Mathf.Deg2Rad * t * 360.0f); txt += $"<voffset={val}em>{plaintext[i]}</voffset>"; t += 0.125f; if (t > 1) t -= 1.0f; } text.SetText(txt); } }