Unity Term Book
Animation & UI

TextMesh Pro

TextMesh Pro là package văn bản cao cấp của Unity — chữ sắc nét mọi kích thước nhờ SDF, kèm rich text tags, font styles, material preset và hiệu ứng chữ.

Hãy tưởng tượng...

Text component cũ như bitmap font — chữ được lưu như hình ảnh, zoom lên thì bị mờ/vỡ. TextMesh Pro dùng SDF (Signed Distance Field) — như vector đồ hoạ — mỗi ký tự là một hàm toán học, zoom to bao nhiêu cũng sắc nét. Ngoài ra, rich text tags trong TMP giống HTML: viết tag color=red trong string là chữ đó đỏ, không cần tạo nhiều Text component.

Khái niệm chi tiết

SDF Rendering: TextMesh Pro tạo SDF texture từ font — mỗi pixel lưu khoảng cách đến viền ký tự gần nhất. Khi render, shader dùng khoảng cách này để tái tạo viền sắc nét dù ở bất kỳ scale nào. Cùng một atlas texture có thể hiện chữ từ 8px đến 200px mà không cần rebuild.

Font Asset là asset TMP cốt lõi — chứa SDF texture và metadata (spacing, kerning, glyphs). Tạo bằng: Window → TextMeshPro → Font Asset Creator. Chọn source font (.ttf/.otf), character set (ASCII, Unicode range), atlas size. Dùng Dynamic Atlas (2021+) để tự thêm glyph theo nhu cầu, tốt cho ngôn ngữ CJK.

Rich Text Tags là hệ thống inline markup: <b>, <i>, <color=#ff0000>, <size=24>, <sprite index=0>, <gradient>, <link=“url”>… Cho phép tạo văn bản giàu định dạng từ một string duy nhất — rất hữu ích cho dialogue system, skill tooltips, damage numbers.

TMP có hai component: TMP_Text (abstract base) với hai variant TextMeshProUGUI (cho UI Canvas) và TextMeshPro (cho World Space/3D). Luôn reference bằng TMP_Text để code tương thích cả hai.

Bảng Rich Text Tags

TagVí dụKết quả
<b>, <i><b>Bold</b> <i>Italic</i>Bold Italic
<color><color=red>danger</color>danger
<color=#hex><color=#f97316>fire</color>fire
<size><size=20>large</size>large
<sprite><sprite="icons" name="coin">🪙 (sprite từ atlas)
<link><link="item_001">Sword</link>Sword
<alpha><alpha=#88>ghost</alpha>ghost
<mark><mark=#ffff00aa>highlight</mark>highlight

Hướng dẫn thực hành

1

Import TMP Essential Resources

Window → TextMeshPro → Import TMP Essential Resources. Bắt buộc cho TMP hoạt động (fonts, shaders, settings).

2

Tạo Font Asset từ font tùy chỉnh

Window → TMP → Font Asset Creator → chọn .ttf font, đặt Atlas Resolution 512×512 trở lên, Generate → Save.

3

Thêm TMP Text component

UI → Text - TextMeshPro cho Canvas. Add Component → TextMeshPro cho World Space. Gán Font Asset.

4

Dùng rich text trong Inspector

Bật "Enable Rich Text" (mặc định on). Nhập text với tags trực tiếp trong Text input field.

5

Thêm tiếng Việt/CJK characters

Font Asset Creator → Character Set → Custom Range → nhập Unicode range của tiếng Việt. Hoặc dùng Dynamic Atlas Mode.

Trình mô phỏng tương tác

Nhập rich text tags để xem preview — tương tự TMP text field trong Unity Inspector.

Preview

Ví dụ Code

Cơ bản

Sử dụng TMP_Text trong script — set text, rich text, và đổi color tại runtime.

using UnityEngine;
using TMPro; // Namespace của TextMesh Pro

public class TMPController : MonoBehaviour
{
  // Dùng TMP_Text để tương thích cả UI và World Space
  [SerializeField] TMP_Text titleText;
  [SerializeField] TMP_Text damageText;

  public void ShowDamage(int amount, bool isCrit)
  {
      if (isCrit)
      {
          // Critical hit: màu vàng, chữ lớn hơn
          damageText.text = $"<color=#fbbf24><size=1.5em><b>CRIT {amount}</b></size></color>";
      }
      else
      {
          damageText.text = $"<color=red>-{amount}</color>";
      }
  }

  public void SetTitle(string name, int level)
  {
      // TMP_Text.SetText() hiệu quả hơn gán .text — không allocate string
      titleText.text = $"{name} <size=0.7em><color=#64748b>Lv.{level}</color></size>";
  }

  // Đổi màu vertex trực tiếp (không cần tag)
  public void SetColor(Color c)
  {
      titleText.color = c;
  }
}

Ví dụ Code

Nâng cao

Typewriter effect — hiển thị chữ từng ký tự qua coroutine, hỗ trợ tags.

using UnityEngine;
using System.Collections;
using TMPro;

public class TypewriterEffect : MonoBehaviour
{
  [SerializeField] TMP_Text dialogText;
  [SerializeField] float charDelay = 0.04f;

  Coroutine current;

  public void ShowText(string text)
  {
      if (current != null) StopCoroutine(current);
      current = StartCoroutine(TypeRoutine(text));
  }

  IEnumerator TypeRoutine(string text)
  {
      dialogText.text = text;
      dialogText.ForceMeshUpdate(); // Rebuild mesh ngay lập tức

      TMP_TextInfo info = dialogText.textInfo;
      int total = info.characterCount;

      // Ẩn tất cả ký tự qua alpha
      for (int i = 0; i < total; i++)
      {
          SetCharAlpha(i, 0);
      }

      // Hiện từng ký tự
      for (int i = 0; i < total; i++)
      {
          SetCharAlpha(i, 255);
          dialogText.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
          yield return new WaitForSeconds(charDelay);
      }
  }

  void SetCharAlpha(int charIdx, byte alpha)
  {
      TMP_TextInfo info = dialogText.textInfo;
      if (charIdx >= info.characterCount) return;
      int matIdx = info.characterInfo[charIdx].materialReferenceIndex;
      int vertIdx = info.characterInfo[charIdx].vertexIndex;
      Color32[] colors = info.meshInfo[matIdx].colors32;
      for (int k = 0; k < 4; k++) colors[vertIdx + k].a = alpha;
  }
}

📌 Ghi nhớ nhanh

  • SDF: sharp text ở mọi size, dùng một atlas duy nhất
  • TextMeshProUGUI: Canvas UI; TextMeshPro: World/3D
  • Reference bằng TMP_Text (base) để code dùng được cả hai
  • ForceMeshUpdate() khi cần truy cập textInfo ngay lập tức
  • Dynamic Atlas Mode cho ngôn ngữ có nhiều ký tự (Vietnamese, CJK)

⚠️ Lỗi thường gặp

  • ❌ Chữ hiện ô vuông □ (tofu)

    Font Asset không có glyph cho ký tự đó

    ✅ Rebuild Font Asset với character range bao gồm Unicode của ngôn ngữ

  • ❌ Rich text tag không có tác dụng

    Enable Rich Text bị tắt trong TMP component

    ✅ Inspector → Extra Settings → Enable Rich Text = ON