Unityで日本語フォント使用時のラグ問題と対策

Unityプロジェクトで日本語フォント、特にTextMeshProを使用してUIを構築する際に、特定のシーンでパフォーマンスが低下し、ラグ(処理遅延)が発生することがあります。このページでは、その主な原因と具体的な対策について解説します。

動画: シーン遷移と「ShopInterior」シーンでのラグ発生の様子

主な原因

1. 【最有力】TextMeshPro フォントアセットの文字セットが大きすぎる

日本語フォントには、ひらがな、カタカナ、そして膨大な数の漢字が含まれています(数千~数万字)。TextMeshProでは、これらの文字情報を「フォントアトラス」というテクスチャに焼き付けて使用します。 もし、フォントアセットを作成する際に、ゲーム内で実際に使用する文字だけでなく、フォントに含まれる全ての文字を対象にしてしまうと、以下のような問題が発生します。

これが、ラグ発生の最も一般的な原因です。

以下の画像は、TextMeshProのUI要素のインスペクターでフォントアセットが設定されている例です。ここで指定されているフォントアセット(例: NotoSansJP-Medium SDF)が最適化されているかが重要になります。

TextMeshPro Inspector Font Asset Setting

画像: TextMeshProのInspectorでのフォントアセット設定例

2. UI要素の数と複雑さ

ラグが発生するシーン(例:「ShopInterior」)で、他のシーンに比べて表示されているUI要素(ボタン、テキスト、パネルなど)の数が多い、またはUIの階層構造が複雑な場合、それ自体がパフォーマンスに影響を与えることがあります。

これに上記1のフォントアセットの問題が組み合わさると、ラグがより顕著になります。

3. フォールバックフォントの処理

指定されたフォントアセットに必要な文字が含まれていない場合、TextMeshProは設定された「フォールバックフォント」から文字を探そうとします。この探索処理が頻繁に、かつ多数の文字に対して発生すると、パフォーマンス低下の一因となることがあります。ただし、主要な原因である可能性は上記1, 2に比べて低いです。

具体的な対策

1. 【最優先】TextMeshPro フォントアセットの最適化(使用文字の限定)

これが最も効果的な対策です。フォントアセットに含める文字を、ゲーム内で実際に使用するものだけに限定します。

手順:

  1. Unityエディタのメニューから Window > TextMeshPro > Font Asset Creator を開きます。
  2. Font Source: 使用したい日本語フォントの元ファイル(例: NotoSansJP-Medium.otfNotoSansJP-Medium.ttf など)を指定します。
  3. Character Set: ドロップダウンメニューから Custom Characters を選択します。
  4. Custom Character List (または Character List / Sequence): 表示されたテキストエリアに、ゲーム内で使用する全ての日本語文字を入力します。
    例: 「あいうえおアイウエオ春夏秋冬一二三四五攻防回買売円ABC123!?、。」
    最初はラグが発生しているシーンで使われている文字(例:「あかさたな」)や、基本的なひらがな・カタカナだけでも試してみて効果を確認しましょう。プロジェクト全体で使う文字をリストアップするのが理想です。
  5. Atlas Resolution: フォントアトラスのテクスチャ解像度を設定します。入力した文字数や必要な品質に応じて調整します。 一般的な目安として、最初は 2048x20484096x4096 を試してみてください。文字数が多い場合はより大きな解像度が必要になることがありますが、大きすぎると逆にメモリを圧迫することもあるためバランスが重要です。TextMeshProが生成時に必要な最小サイズを提案してくれることもあります。
  6. Font Padding: 文字間の余白です。通常はデフォルト値(例: 5)のままで問題ありませんが、文字が欠ける場合は調整します。
  7. Render Mode: DISTANCE_FIELD_16DISTANCE_FIELD_32 など、SDF (Signed Distance Field) を利用したモードを選択すると、様々なフォントサイズでも綺麗に表示されやすくなります。
  8. Generate Font Atlas ボタンをクリックします。
  9. 保存ダイアログが表示されるので、新しい名前でフォントアセットを保存するか、既存のフォントアセット(例: NotoSansJP-Medium SDF)を上書きします。
    注意: 既存のアセットを上書きする場合は、念のため事前にプロジェクトのバックアップを取るか、元のアセットを複製しておくことをお勧めします。
  10. 最適化された新しいフォントアセットを、日本語テキストを表示しているTextMeshProコンポーネント(TextMeshPro - Text (UI)TextMeshPro - Input Field など)の Font Asset プロパティに設定します。 上記で埋め込んだ画像(textmeshpro_inspector.png)の「Font Asset」スロットが、この設定箇所に該当します。ここに、最適化して生成したフォントアセットを改めて設定してください。

期待される効果:

2. UI要素の負荷軽減

特にUI要素が多いシーンでは、以下の最適化も検討しましょう。

3. Unity Profiler を使用したボトルネックの特定

具体的な処理のどこに時間がかかっているかを正確に把握するためには、Unity Profilerが非常に有効なツールです。

手順の概要:

  1. ラグが発生するシーンを再生中に、Unityエディタのメニューから Window > Analysis > Profiler を開きます。
  2. CPU Usage プロファイラを選択し、処理に時間がかかっている関数や処理系統を確認します。 特に、TextMeshPro.UpdateFontAsset, Canvas.BuildBatch, TextGeneration, Font.CacheFontForText といったUI関連やテキストレンダリング関連の処理に注目します。
  3. GPU Usage プロファイラも確認し、描画負荷が高すぎないか確認します。

Profilerを使用することで、推測ではなくデータに基づいて問題箇所を特定し、より的確な対策を講じることができます。

SceneController.cs について


// --- START OF FILE SceneController.cs ---

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // UnityEngine.UIは直接使用されていませんが、UI操作の関連で含まれることがあります
using UnityEngine.SceneManagement;

public class SceneController : MonoBehaviour
{
    public void SceneIsland()
    {
        SceneManager.LoadScene("Island");
    }

    public void SceneRoom()
    {
        SceneManager.LoadScene("Room");
    }

    public void SceneShopInterior()
    {
        SceneManager.LoadScene("ShopInterior");
    }
}
// --- END OF FILE SceneController.cs ---
        

このスクリプトは、SceneManager.LoadScene() を使用してシーンを切り替える標準的な方法です。 このスクリプト自体が、特定のシーンで日本語フォントを表示した際の継続的なラグの直接的な原因となっているとは考えにくいです。 シーンのロード時間(切り替えにかかる時間)が長い場合は、シーンに含まれるアセットの総量や初期化処理などが影響しますが、今回の「表示後のラグ」とは別の問題として切り分けることができます。

まとめ

Unityで日本語フォントを使用する際にラグが発生する場合、最も可能性の高い原因はTextMeshProのフォントアセットが最適化されていないことです。 まずは、本ページで解説した「TextMeshPro フォントアセットの最適化(使用文字の限定)」の手順を試し、ゲーム内で使用する文字だけに絞り込んだフォントアセットを作成・適用してみてください。

それでも改善しない場合や、さらにパフォーマンスを追求したい場合は、UI要素の最適化やUnity Profilerによる詳細なボトルネック調査を進めていくと良いでしょう。