TextMesh Pro
TextMesh Pro 是 Unity 的高级文字渲染包,通过 SDF 技术在任意尺寸下保持清晰字形,并支持富文本标签、字体样式、材质预设与复杂文字特效。它是 UI 与世界空间文字的事实标准,帮助本地化项目处理多语言排版、字体回退与图文混排需求,并让 HUD、对话气泡与伤害数字更加锐利、清晰美观。
想象一下...
旧的 Text 组件是位图字体——字形是图片,放大就会糊。TextMesh Pro 使用 SDF(Signed Distance Field)——更像矢量图——每个字符是数学函数,任意尺寸都清晰。Rich text tags 像 HTML:在字符串里写 color=red,那段就变红,无需额外 Text 组件。
概念详解
SDF Rendering:TextMesh Pro 从字体生成 SDF texture——每个像素存储到最近字形边缘的距离。渲染时 shader 在任意缩放下重建清晰轮廓。 同一 atlas 可显示 8px 到 200px,无需重建。
Font Asset 是 TMP 的核心资源——SDF 纹理加元数据 (字距、kerning、字形)。创建路径:Window → TextMeshPro → Font Asset Creator。 选择源字体(.ttf/.otf)、字符集(ASCII、Unicode 范围)、atlas 尺寸。 使用 Dynamic Atlas(2021+)可按需添加字形——适合中日韩。
Rich Text Tags 是内联标记:
<b>、
<i>、
<color=#ff0000>、
<size=24>、
<sprite index=0>、
<gradient>、
<link=“url”>…
一条字符串即可承载丰富格式——对话、技能提示、伤害数字。
TMP 有两个组件:
TMP_Text
(抽象基类),以及
TextMeshProUGUI
(Canvas UI)和
TextMeshPro
(World Space/3D)。始终引用
TMP_Text,
同一套代码即可兼顾两者。
Rich Text 标签参考
| Tag | 示例 | 结果 |
|---|---|---|
| <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) |
| <link> | <link="item_001">Sword</link> | Sword |
| <alpha> | <alpha=#88>ghost</alpha> | ghost |
| <mark> | <mark=#ffff00aa>highlight</mark> | highlight |
动手步骤
导入 TMP Essential Resources
Window → TextMeshPro → Import TMP Essential Resources。TMP 正常工作所必需(字体、shader、设置)。
从自定义字体创建 Font Asset
Window → TMP → Font Asset Creator → 选 .ttf,Atlas Resolution 512×512 或更高,Generate → Save。
添加 TMP Text 组件
UI → Text - TextMeshPro 用于 Canvas。Add Component → TextMeshPro 用于 World Space。指定 Font Asset。
在 Inspector 中使用富文本
保持 "Enable Rich Text" 开启(默认)。直接在 Text 字段输入标签。
添加越南语/中日韩字符
Font Asset Creator → Character Set → Custom Range → 输入 Unicode 范围。或使用 Dynamic Atlas Mode。
交互模拟器
输入富文本标签预览——类似 Unity Inspector 中的 TMP 字段。
Preview
代码示例
基础用脚本操作 TMP_Text——运行时设置文字、富文本与颜色。
using UnityEngine;
using TMPro; // TextMesh Pro namespace
public class TMPController : MonoBehaviour
{
// TMP_Text works for both UI and World Space
[SerializeField] TMP_Text titleText;
[SerializeField] TMP_Text damageText;
public void ShowDamage(int amount, bool isCrit)
{
if (isCrit)
{
// Critical hit: gold, larger type
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() can be cheaper than assigning .text
titleText.text = $"{name} <size=0.7em><color=#64748b>Lv.{level}</color></size>";
}
// Vertex color without tags
public void SetColor(Color c)
{
titleText.color = c;
}
}代码示例
进阶打字机效果——用协程逐字显现,标签一并支持。
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 the mesh immediately
TMP_TextInfo info = dialogText.textInfo;
int total = info.characterCount;
// Hide every character via alpha
for (int i = 0; i < total; i++)
{
SetCharAlpha(i, 0);
}
// Reveal one by one
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;
}
}📌 快速记忆
- ▸SDF:同一 atlas 任意尺寸都清晰
- ▸TextMeshProUGUI:Canvas UI;TextMeshPro:World/3D
- ▸引用 TMP_Text(基类),一套脚本兼顾两者
- ▸需要立刻读 textInfo 时调用 ForceMeshUpdate()
- ▸大字符集(越南语、中日韩)用 Dynamic Atlas Mode
⚠️ 常见错误
❌ 字符显示为 □(豆腐块)
Font Asset 没有该字符的字形
✅ 用覆盖该语言的 Unicode 范围重建 Font Asset
❌ 富文本标签无效
TMP 组件上 Enable Rich Text 关闭
✅ Inspector → Extra Settings → Enable Rich Text = ON