关于 optimize-text-mesh-pro
面向 Unity 开发者的 TextMeshPro 优化排障技能,涵盖内存、渲染、性能、构建体积和多语言对齐。它先按症状分类,再提供针对性的配置建议。
主要功能
- 01按症状分类排障
- 02字体图集与回退配置建议
- 03采样参数和字体缩放调整
- 04AutoSize 与 Canvas 性能建议
- 05多语言字体及对齐指导
- 06材质预设使用建议
适用场景
- 01排查过大的 TMP 图集
- 02减少文本更新时的 CPU 峰值
- 03缩小多语言移动端构建体积
- 04校准拉丁文与 CJK 混排文本
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ unity-technologies/ skills --skill optimize-text-mesh-pro安装后在 Claude Code 中输入/optimize-text-mesh-pro确认已加载。
详细介绍
优化 TextMeshPro
分类——先识别问题症状
提供建议前,先确定用户的问题属于哪一类。如果用户没有描述具体症状,请询问:“TextMeshPro 是否存在内存/图集膨胀、视觉质量、CPU/性能、构建体积或本地化/对齐问题?”
| 症状 | 前往 |
|---|---|
| Memory Profiler 显示 TMP 图集过大或数量过多 | 字体栈与动态回退、Memory Profiler:包含字体数据 |
| 字形粗细不一致、边缘模糊、视觉质量不佳 | 边距与采样比例、字体资源缩放、图集渲染模式:SDF16 |
| 文本更新或 Canvas 重建期间出现 CPU 峰值 | 自动调整大小、世界空间文本与 Canvas 文本 |
| 发布的字体文件导致构建体积过大 | 动态操作系统图集填充 |
| 拉丁文与 CJK 混排时对齐效果不佳 | 字体规范化 |
| 需要多种字体样式(斜体、描边、发光) | 材质预设 |
核心规则
- 主字体 = 包含所有字形的静态资源。 通过回退列表(或 TMP 设置)添加动态回退字体来处理其他字形。将动态图集大小保持在 512-1024,以限制峰值内存。
- 动态回退字体 -> 启用
Clear Dynamic Data On Build。 否则,编辑器中生成的字形会随应用一起打包。 - 主字体和回退字体的边距与采样点大小之比必须保持一致。 比例不匹配会导致同一行中的字形粗细不一致。
- 拉丁文采样点大小设为 70-90;CJK 设为 36-50。 不同文字需要不同的采样大小,才能获得清晰的 SDF。
- 字体资源 Scale = 1。 任何其他值(例如 0.9)都会破坏标准点大小计算方式。
- 布局确定后,在运行时禁用 AutoSize。 AutoSize 用于设计阶段,不适合实时计数器。
- 世界空间文本 -> 使用
TextMeshPro,而非TextMeshProUGUI。 世界空间中的 Canvas 开销并非免费。 - 将经常变化的 TMP UI 放在独立 Canvas 中,以限制重建开销。
- 对于同一字体的斜体/粗体/描边/发光样式,优先使用 TMP 材质预设,而不是复制字体资源。
- 在 iOS/Android 上发布多语言构建时,请评估
Atlas Population Mode = Dynamic OS(TMP 3.2.0-pre.3+),以利用系统字体并缩小构建体积。
字体栈与动态回退
如果用户反馈 TMP 图集导致内存膨胀,请建议采用以下字体栈模式:
Main font asset (static, all required Latin glyphs baked)
-> Fallback 1: Dynamic font (atlas 512 or 1024) for CJK
-> Fallback 2: Dynamic font for symbols / emoji
切勿发布未启用 Clear Dynamic Data On Build 的动态回退字体资源。 如果关闭此开关,编辑器测试期间生成的每个字形都会包含在应用构建中。
边距与采样比例
如果用户反馈主字体与回退字体的笔画宽度或字形粗细不一致,请检查边距与采样点大小之比。
比例为 Padding / SamplingPointSize。当 Padding = 9 且 Sampling Point Size = 90 时,比例为 10%。
- 主字体和回退字体的比例不同,会导致同一行中的笔画宽度不一致。
- 选择一个比例(10% 是稳妥的默认值),并将其应用于字体链中的所有字体资源。
建议的采样点大小:
- 拉丁文脚本:70-90。
- CJK 脚本:36-50(CJK 字形的视觉密度更高;较小的采样大小仍可生成清晰的 SDF,并节省图集内存)。
字体资源缩放
如果用户反馈点大小与设计规格不符,请检查字体资源的 Scale 值。有些导入的 TMP 字体资源的 Scale 为 0.9,而非 1.0。Scale 值会参与点大小到像素的计算,因此非 1 的缩放值会导致点大小不符合标准。建议用户在调整边距比例之前,将所有字体资源的 Scale 设为 1。
Sprite 资源
如果用户反馈 TMP Sprite Assets 在移动设备上加载缓慢,请检查源纹理的 Texture Type。必须设为 Default(而非 Sprite)。Sprite 类型会创建 TMP 不使用的子对象;设为 Default 可避免创建这些对象。
AutoSize
如果用户反馈频繁变化的文本字段(计时器、计数器、聊天内容、动态玩家名称)出现 CPU 峰值,请检查是否启用了 enableAutoSizing。AutoSize 会在字符串变化时调整文本大小,导致 CPU 持续出现峰值。
建议:布局确定后,禁用 AutoSize,并将选定的字号设为固定值。仅对确实需要在区域设置变化时自动适应的静态标签启用 AutoSize。
图集渲染模式:SDF16
如果点大小为 72 或更大的静态字体显示不清晰或边缘模糊,建议将 Atlas Render Mode 切换为 SDF16。它能为大字形提供更高精度的 SDF,但会略微增加图集内存占用。
字体规范化
如果用户反馈同一行中的拉丁文字和 CJK 文字未对齐,请引导他们完成以下步骤:
- Window -> TextMeshPro -> Settings -> Import TMP Example & Extras(每个项目只需执行一次)。
- 将
TMP_TextInfoDebugTool组件添加到显示未对齐文本的 TextMeshPro 对象。 - 启用 ShowLines 开关——升部线、降部线和基线将以叠加层形式显示。
- 混排拉丁文字和 CJK 文字;如果这些线彼此偏离,调整 TMP Font Asset 上的 ascender/descender,直到对齐。
注意:据观察,在某些项目布局中导入 TMP Examples & Extras 会导致无限导入循环。如果发生这种情况,请关闭 Unity 并重新打开——第二次尝试时即可完成导入。
材质预设
如果用户需要同一字体的多种样式(斜体、粗体、描边、辉光),建议使用材质预设,而不是复制字体资源。预设共享同一字体纹理,但会覆盖着色器参数。
创建方法:
- 选择一个 TMP Text GameObject。
- 在 Inspector 中找到 Material 部分。
- 右键单击 Material 标题 -> Create Material Preset。
- 重命名新材质并调整设置。
- 在 TMP Text 组件上,从 Material Preset 下拉菜单中选择该预设。
动态 OS 图集填充(TMP 3.2.0-pre.3)
如果用户要发布多语言构建版本并关注构建大小,建议评估 Atlas Population Mode = Dynamic OS(TMP 3.2.0-pre.3+):
- 在 Editor 中:仍使用项目中的源字体。
- 在播放器构建版本中:不包含源字体。运行时,Unity 会在设备上查找 Family + Style 名称匹配的字体。
推荐用于 CJK 的系统字体:
| 平台 | 推荐的系统字体 |
|---|---|
| Android | NotoSans(广泛覆盖中文、日文和韩文字形)。 |
| iOS | 简体中文和繁体中文使用 PingFang。iOS 对 CJK 每种语言使用不同的字体(中文、日文和韩文使用不同的字体系列)——如果要让单个 TMP 设置支持这三种语言,请检查回退链。 |
优点:构建大小缩小(无需随构建发布 CJK 字体文件),内存占用也会降低(系统字体与 OS 共享)。
内存分析器:包含字体数据
如果内存分析器显示 Editor 中的字体资源大小异常大,请检查 .ttf / .ttc 导入设置中是否启用了 Include Font Data。默认情况下,Editor 会将源字体文件包含在资源中;但在设备上(尤其是使用 Dynamic OS 时)无需承担这部分开销。
要让 Editor 捕获结果与设备上的情况一致:在字体文件的导入设置中,取消选择 Include Font Data。此后,内存分析器显示的开销将不包含底层字体文件。
世界空间文本与 Canvas 文本
如果用户使用 TextMeshProUGUI 显示世界空间文本(伤害数字、标牌、全息影像),建议改用 TextMeshPro。世界空间 Canvas 是已知的低效做法。
如果 TextMeshProUGUI 元素的 text 经常变化(计时器、计数器、聊天内容),建议将其设为带有独立 Canvas 组件的子 GameObject 的子对象。Canvas 重建按 Canvas 分别进行,因此将易变字段隔离开来,可以降低 UI 其余部分的重建成本。
常见陷阱
如果用户的设置符合以下任一情况,请指出:
- 用一个大型动态字体资源覆盖所有语言,而不是使用静态主字体加动态回退字体——动态图集会急剧膨胀。
- 主字体与回退字体的内边距比例不一致——同一行文本看起来像是用了两种字体。
- 字体资源的 Scale = 0.9,且该值从导入设置继承而来——字号将无法符合设计规范。
- 为实时更新的计数器启用 AutoSize——会导致难以察觉的 CPU 峰值。
- 在世界空间 Canvas 中使用世界空间
TextMeshProUGUI——会造成额外重建,却没有任何好处;应改用TextMeshPro。 - 忘记为动态回退字体启用 Clear Dynamic Data On Build——编辑器测试时生成的字形会随之打包进播放器。
- 在启用 Include Font Data 的情况下,于 Editor 中使用 Memory Profiler 捕获数据,之后却对设备端构建体积更小感到意外。
- 将 Sprite 资源的源纹理类型设为 Sprite——额外的子对象会拖慢移动设备上的加载速度。
参考资料
- TextMeshPro - 图集填充模式(Unity 手册):https://docs.unity3d.com/Packages/com.unity.textmeshpro@latest/manual/FontAssets.html