LoginSignup
4
1

More than 1 year has passed since last update.

【Unity】TextMeshProのAutoSizeは重いと聞いたので、フォントサイズをまとめて調整できる便利メソッドを作った

Posted at

概要

TMP の AutoSize は処理負荷が重いと聞いたので、TextMeshPro を任意のタイミングで AutoSize(を模した処理)をする拡張メソッドを作りました。
また画像のように、複数の TextMeshPro から一番文字列の長い要素を探して AutoSize を行い、そのフォントサイズを全ての TextMeshPro に適応する便利メソッドも作りました。AutoSize を1回に抑え、見た目の統一感も保てます。
TextMeshPro の拡張クラスや便利クラスに追加してご利用ください。

before.png
after.png

コード

TMProExtension.cs
TMProExtension.cs
using UnityEngine;
using TMPro;

/// <summary>
/// TextMeshProの拡張クラス
/// </summary>
public static class TMProExtension
{
    /// <summary>
    /// TextがRectに収まるように、フォントサイズを調整する
    /// </summary>
    /// <param name="text">Text</param>
    /// <param name="scale">Rectに対しての大きさ</param>
    /// <param name="maxSize">最大フォントサイズ</param>
    public static float FitFontSize(this TMP_Text text,
        float scale = 0.9f,
        float maxSize = 1024f)
    {
        text.fontSize = 1f;

        float textWidth = text.preferredWidth;
        float textHeight = text.preferredHeight;
        Rect rect = text.rectTransform.rect;
        float rectWidth = rect.width;
        float rectHeight = rect.height;

        if (text.text.Length == 0
            || Mathf.Approximately(textHeight, 0f)
            || Mathf.Approximately(rectWidth, 0f)
            || Mathf.Approximately(rectHeight, 0f)) return 0f;

        float rateX = textWidth / rectWidth;
        float rateY = textHeight / rectHeight;

        if (rateX > rateY) text.fontSize = Mathf.Min(maxSize, scale / rateX);
        else text.fontSize = Mathf.Min(maxSize, scale / rateY);

        return text.fontSize;
    }
}

TMProUtility.cs
TMProUtility.cs
using System.Collections.Generic;
using TMPro;

/// <summary>
/// TextMeshProの便利クラス
/// </summary>
public static class TMProUtility
{
    /// <summary>
    /// 一番文字列の長いTextを探し、自身のRectに収まるフォントサイズを計算。それを全てのTextのフォントサイズに適応する
    /// </summary>
    /// <param name="text">Text</param>
    /// <param name="scale">Rectに対しての大きさ</param>
    /// <param name="maxSize">最大フォントサイズ</param>
    public static void FitsAllFontSize(
        this TMP_Text[] texts,
        float scale = 0.9f,
        float maxSize = 256f)
    {
        // 最長文字列の TMP_Text を探す
        TMP_Text t = null;
        int maxLength = 0;
        foreach (var item in texts)
        {
            if (item.text.Length > maxLength)
            {
                t = item;
                maxLength = item.text.Length;
            }
        }

        // フォントサイズを決定
        float size = t.FitFontSize(scale, maxSize);

        // 全てのTextに適応
        foreach (var text in texts)
        {
            text.fontSize = size;
        }
    }
}

使い方

AutoSize(を模した処理)は下記で実行できます。重い処理です。

text.FitFontSize();

引数は2つ用意されています。

text.FitFontSize(scale: 0.9f, maxSize: 256f);

FitsAllFontSize を使うと、複数の TextMeshPro から一番文字列の長い要素を探して AutoSize を行い、そのフォントサイズを全ての TextMeshPro に適応できます。たくさん改行する文字列は上下にはみ出す恐れがあります。

TMProUtility.FitsAllFontSize(texts);

こちらにも FitFontSize と同様の引数が用意されています。

TMProUtility.FitsAllFontSize(texts, scale: 0.9f, maxSize: 256f);

補足

以前作った任意のタイミングでフォントサイズを調整できるコンポーネントは、AutoSize の使用頻度を抑えられていない失敗作だと気づいたため、改良したものを作りました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1