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
| Tag | Ví 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
Import TMP Essential Resources
Window → TextMeshPro → Import TMP Essential Resources. Bắt buộc cho TMP hoạt động (fonts, shaders, settings).
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.
Thêm TMP Text component
UI → Text - TextMeshPro cho Canvas. Add Component → TextMeshPro cho World Space. Gán Font Asset.
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.
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ảnSử 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 caoTypewriter 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