optimize-text-mesh-pro

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Optimize TextMeshPro

TextMeshPro优化

Triage — identify the symptom first

问题排查——先确定症状

Before providing tips, identify which category the user's issue falls into. If the user has not described a specific symptom, ask: "Are you seeing a memory/atlas bloat, visual quality, CPU/performance, build size, or localization/alignment issue with TextMeshPro?"
SymptomGo To
Memory Profiler shows large or multiple TMP atlasesFont Stack & Dynamic Fallbacks, Memory Profiler: Include Font Data
Inconsistent glyph weight, fuzzy edges, visual qualityPadding & Sampling Ratios, Font Asset Scale, Atlas Render Mode: SDF16
CPU spikes during text updates or Canvas rebuildsAutoSize, Worldspace vs Canvas Text
Build size too large from shipped font filesDynamic OS Atlas Population
Mixed Latin + CJK alignment looks offFont Normalization
Need multiple font styles (italic, outline, glow)Material Presets

在提供优化建议前,先确定用户的问题属于哪一类别。如果用户未描述具体症状,请询问:“您遇到的是TextMeshPro的内存/图集膨胀视觉质量CPU/性能构建体积,还是本地化/对齐问题?”
症状跳转至
Memory Profiler显示大型或多个TMP图集字体栈与动态回退Memory Profiler:包含字体数据
字形粗细不一致、边缘模糊、视觉质量问题内边距与采样比率字体资源缩放图集渲染模式:SDF16
文本更新或Canvas重建时CPU峰值AutoSize世界空间文本 vs Canvas文本
字体文件导致构建体积过大动态系统图集生成
拉丁文字与CJK文字混合时对齐异常字体归一化
需要多种字体样式(斜体、描边、发光)材质预设

Core Rules

核心规则

  • Main font = static asset with all glyphs baked in. Add dynamic fallbacks via the Fallback list (or TMP Settings) for everything else. Keep dynamic atlas size at 512-1024 to bound peak memory.
  • Dynamic fallback fonts -> enable
    Clear Dynamic Data On Build
    .
    Otherwise editor-baked glyphs ship in the player.
  • Keep Padding-to-Sampling-Point-Size ratio consistent across primary + fallback fonts. Mismatch produces inconsistent glyph weight on the same line.
  • Latin sampling point size 70-90; CJK 36-50. Different scripts need different sampling sizes for clean SDF.
  • Font asset Scale = 1. Anything else (e.g., 0.9) breaks standard point-size math.
  • Disable AutoSize at runtime once layout is locked. AutoSize is for design, not for live counters.
  • Worldspace text -> use
    TextMeshPro
    , not
    TextMeshProUGUI
    .
    Canvas overhead in worldspace is not free.
  • Parent often-changing TMP UI to its own Canvas to bound rebuild cost.
  • TMP material presets > duplicating font assets for italic / bold / outline / glow variants of the same font.
  • For shipping multilingual builds on iOS/Android, evaluate
    Atlas Population Mode = Dynamic OS
    (TMP 3.2.0-pre.3+) to leverage system fonts and shrink the build.

  • 主字体 = 包含所有预烘焙字形的静态资源。通过回退列表(或TMP设置)为其他内容添加动态回退字体。将动态图集大小设置为512-1024,以限制峰值内存占用。
  • 动态回退字体 -> 启用
    Clear Dynamic Data On Build
    。否则,编辑器中烘焙的字形会被打包到玩家构建版本中。
  • 保持主字体与回退字体的内边距-采样点大小比率一致。比率不匹配会导致同一行文本的字形粗细不一致。
  • 拉丁文字采样点大小70-90;CJK文字36-50。不同脚本需要不同的采样大小来生成清晰的SDF。
  • 字体资源缩放值 = 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及以上版本),以利用系统字体并减小构建体积。

Font Stack & Dynamic Fallbacks

字体栈与动态回退

If the user reports memory bloat from TMP atlases, advise this font stack pattern:
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
NEVER ship a dynamic fallback font asset without enabling
Clear Dynamic Data On Build
.
Every glyph baked while testing in the editor is included in the player build if this toggle is off.

如果用户反馈TMP图集导致内存膨胀,建议采用以下字体栈模式:
主字体资源(静态,预烘焙所有所需拉丁文字形)
  -> 回退字体1:动态字体(图集大小512或1024),用于CJK文字
  -> 回退字体2:动态字体,用于符号/表情
切勿在未启用
Clear Dynamic Data On Build
的情况下发布动态回退字体资源
。如果关闭此开关,编辑器测试期间烘焙的所有字形都会被包含在玩家构建版本中。

Padding & Sampling Ratios

内边距与采样比率

If the user reports inconsistent stroke widths or glyph weight differences between primary and fallback fonts, check the padding-to-sampling-point-size ratio.
The ratio is
Padding / SamplingPointSize
. With Padding = 9 and Sampling Point Size = 90, ratio = 10%.
  • A primary font with one ratio and a fallback with a different ratio produces inconsistent stroke widths on the same line.
  • Pick a ratio (10% is a safe default), apply it to all font assets in the chain.
Recommended sampling point sizes:
  • Latin scripts: 70-90.
  • CJK scripts: 36-50 (CJK glyphs are visually denser; smaller sampling sizes still produce clean SDF and save atlas memory).

如果用户反馈主字体与回退字体之间存在笔画宽度不一致或字形粗细差异,请检查内边距与采样点大小的比率。
比率计算公式为
内边距 / 采样点大小
。当内边距=9、采样点大小=90时,比率为10%
  • 主字体与回退字体的比率不同,会导致同一行文本的笔画宽度不一致
  • 选择一个比率(10%是安全的默认值),并应用于字体链中的所有字体资源。
推荐的采样点大小:
  • 拉丁文字脚本:70-90。
  • CJK文字脚本:36-50(CJK字形视觉密度更高;较小的采样大小仍能生成清晰的SDF并节省图集内存)。

Font Asset Scale

字体资源缩放

If the user reports point sizes not matching design specs, check the font asset Scale value. Some imported TMP font assets ship with
Scale = 0.9
instead of
1.0
. The Scale value participates in the point-size-to-pixels math, so a non-1 scale produces non-standard point sizes. Advise the user to set Scale = 1 on all font assets before adjusting padding ratios.

如果用户反馈点大小与设计规格不符,请检查字体资源的缩放值。部分导入的TMP字体资源默认缩放值为
0.9
而非
1.0
。缩放值会参与点大小到像素的计算,因此非1的缩放值会导致非标准的点大小。建议用户在调整内边距比率前,将所有字体资源的缩放值设置为1

Sprite Assets

精灵资源

If the user reports slow loading times for TMP Sprite Assets on mobile, check the source texture's Texture Type. It must be set to Default (not Sprite). Sprite type creates child sub-objects that TMP doesn't use; Default avoids them.

如果用户反馈移动端TMP精灵资源加载缓慢,请检查源纹理的纹理类型。必须设置为Default(而非Sprite)。Sprite类型会创建TMP不需要的子对象;Default类型可避免此问题。

AutoSize

AutoSize

If the user reports CPU spikes on text fields that change frequently (timers, counters, chat, dynamic player names), check whether
enableAutoSizing
is on. AutoSize resizes the text whenever the string changes, causing constant CPU spikes.
Advise: disable AutoSize and hard-code the chosen point size once layout is locked. Keep AutoSize on only for genuinely static labels that auto-fit on locale change.

如果用户反馈频繁变化的文本字段(计时器、计数器、聊天消息、动态玩家名称)出现CPU峰值,请检查
enableAutoSizing
是否开启。AutoSize会在字符串变化时调整文本大小,导致持续的CPU峰值。
建议:布局锁定后,禁用AutoSize并硬编码选定的点大小。仅在真正需要根据语言环境自动适配的静态标签上保留AutoSize。

Atlas Render Mode: SDF16

图集渲染模式:SDF16

If a static font with point size 72 or larger looks unclear or has fuzzy edges, advise switching the Atlas Render Mode to SDF16. Higher precision SDF for big glyphs, at slightly more atlas memory.

如果点大小为72或更大的静态字体显示模糊或边缘不清,建议将图集渲染模式切换为SDF16。更高精度的SDF适用于大字形,仅会略微增加图集内存占用。

Font Normalization

字体归一化

If the user reports misaligned Latin + CJK text on the same line, walk them through this procedure:
  1. Window -> TextMeshPro -> Settings -> Import TMP Example & Extras (one-time per project).
  2. Add the
    TMP_TextInfoDebugTool
    component to the TextMeshPro object displaying misaligned text.
  3. Enable ShowLines toggle - the ascender, descender, and baseline render as overlays.
  4. Mix Latin + CJK strings; if the lines diverge, adjust ascender/descender on the TMP Font Asset until they align.
Caveat: importing TMP Examples & Extras has been observed to cause an infinite import loop on some project layouts. If it happens, close Unity and re-open - the import resolves on the second attempt.

如果用户反馈同一行中拉丁文字与CJK文字对齐异常,请按照以下步骤操作:
  1. Window -> TextMeshPro -> Settings -> Import TMP Example & Extras(每个项目仅需执行一次)。
  2. 为显示对齐异常文本的TextMeshPro对象添加**
    TMP_TextInfoDebugTool
    **组件。
  3. 启用ShowLines开关——上升线、下降线和基线会以叠加层形式显示。
  4. 混合拉丁文字与CJK文字;如果线条偏移,调整TMP字体资源的上升线/下降线直至对齐。
注意:在部分项目布局中,导入TMP Examples & Extras可能会导致无限导入循环。如果发生此情况,关闭Unity并重新打开——第二次导入即可解决问题。

Material Presets

材质预设

If the user needs multiple styles (italic, bold, outline, glow) of the same font, advise material presets instead of duplicating font assets. Presets share the same font texture but override shader parameters.
How to create:
  1. Select a TMP Text GameObject.
  2. In Inspector, find the Material section.
  3. Right-click the Material header -> Create Material Preset.
  4. Rename the new material and tweak settings.
  5. On the TMP Text component, pick the preset from the Material Preset dropdown.

如果用户需要同一字体的多种样式(斜体、粗体、描边、发光),建议使用材质预设而非复制字体资源。预设共享同一字体纹理,但会覆盖着色器参数。
创建方法:
  1. 选择一个TMP Text游戏对象。
  2. 在Inspector面板中找到Material部分。
  3. 右键点击Material标题 -> Create Material Preset
  4. 重命名新材质并调整设置。
  5. 在TMP Text组件中,从Material Preset下拉菜单中选择该预设。

Dynamic OS Atlas Population (TMP 3.2.0-pre.3)

动态系统图集生成(TMP 3.2.0-pre.3)

If the user is shipping multilingual builds and concerned about build size, advise evaluating
Atlas Population Mode = Dynamic OS
(TMP 3.2.0-pre.3+):
  • In Editor: still uses the source font from the project.
  • In a player build: the source font is not included. At runtime, Unity searches the device for a font with the matching Family + Style name.
Recommended system fonts for CJK:
PlatformRecommended system font
AndroidNotoSans (covers Chinese, Japanese, Korean glyphs broadly).
iOSPingFang for Simplified/Traditional Chinese. iOS uses unique fonts per language for CJK (different families for Chinese, Japanese, Korean) - check the fallback chain when shipping a single TMP setup across all three.
Wins: build size shrinks (no shipped CJK font files) and memory drops (system font is shared with the OS).

如果用户发布多语言版本且担心构建体积,建议评估启用**
Atlas Population Mode = Dynamic OS
**(TMP 3.2.0-pre.3及以上版本):
  • 在编辑器中:仍使用项目中的源字体。
  • 在玩家构建版本中:不包含源字体。运行时,Unity会在设备中搜索匹配Family + Style名称的字体。
推荐的CJK系统字体:
平台推荐系统字体
AndroidNotoSans(广泛覆盖中文、日文、韩文字形)。
iOSPingFang(适用于简体/繁体中文)。iOS针对CJK使用不同语言对应不同字体(中文、日文、韩文分属不同字体家族)——当使用单一TMP设置覆盖三种语言时,请检查回退链。
优势:构建体积减小(无需打包CJK字体文件),内存占用降低(系统字体与操作系统共享)。

Memory Profiler: Include Font Data

Memory Profiler:包含字体数据

If Memory Profiler shows unexpectedly large font asset sizes in the Editor, check whether Include Font Data is enabled on the
.ttf
/
.ttc
import settings. The Editor includes the source font file in the asset by default, but on device (especially with Dynamic OS), this cost is not paid.
To make Editor captures match device: on the font file -> deselect Include Font Data in the import settings. Memory Profiler will then show overhead without the underlying font file.

如果编辑器中的Memory Profiler显示字体资源大小异常,请检查
.ttf
/
.ttc
导入设置中的Include Font Data是否启用。编辑器默认会将源字体文件包含在资源中,但在设备上(尤其是启用Dynamic OS时)不会产生此开销。
为使编辑器捕获结果与设备一致:在字体文件的导入设置中取消勾选Include Font Data。此时Memory Profiler将显示不包含底层字体文件的内存开销。

Worldspace vs Canvas Text

世界空间文本 vs Canvas文本

If the user has worldspace text (damage numbers, signs, holograms) using
TextMeshProUGUI
, advise switching to
TextMeshPro
. Worldspace Canvas is a known inefficiency.
If a
TextMeshProUGUI
element's
text
changes often (timers, counters, chat), advise parenting it under a child GameObject with its own Canvas component. Canvas rebuilds are scoped per-Canvas, so isolating the volatile field cuts rebuild cost on the rest of the UI.

如果用户使用
TextMeshProUGUI
实现世界空间文本(伤害数字、标牌、全息图),建议切换为**
TextMeshPro
**。世界空间Canvas是已知的低效实现。
如果
TextMeshProUGUI
元素的
text
频繁变化(计时器、计数器、聊天消息),建议将其挂载到带有独立Canvas组件的子游戏对象下。Canvas重建是按Canvas范围进行的,因此隔离频繁变化的字段可减少其余UI的重建成本。

Common Pitfalls

常见陷阱

If the user's setup matches any of these, flag it:
  • One giant dynamic font asset for all languages instead of static main + dynamic fallback - the dynamic atlas balloons.
  • Inconsistent padding ratio across primary + fallback - same line of text looks like two fonts.
  • Font asset Scale = 0.9 inherited from import - point sizes won't match design specs.
  • Leaving AutoSize on for live counters - hidden CPU spikes.
  • World-space
    TextMeshProUGUI
    inside a worldspace Canvas - extra rebuilds for no benefit; use
    TextMeshPro
    .
  • Forgetting Clear Dynamic Data On Build on dynamic fallback fonts - editor-test glyphs ship in the player.
  • Capturing Memory Profiler in Editor with Include Font Data on, then being surprised the on-device build is smaller.
  • Sprite asset source texture set to Sprite type - mobile loading slows from extra child sub-objects.

如果用户的设置符合以下任一情况,请指出问题:
  • 使用单个大型动态字体资源覆盖所有语言,而非静态主字体+动态回退字体——动态图集会急剧膨胀。
  • 主字体与回退字体的内边距比率不一致——同一行文本看起来像两种字体。
  • 字体资源继承导入时的缩放值=0.9——点大小与设计规格不符。
  • 实时计数器仍启用AutoSize——存在隐藏的CPU峰值。
  • 世界空间Canvas中使用
    TextMeshProUGUI
    ——无意义地增加重建开销;应使用
    TextMeshPro
  • 动态回退字体未启用Clear Dynamic Data On Build——编辑器测试时的字形被打包到玩家构建版本中。
  • 编辑器中启用Include Font Data时捕获Memory Profiler,却惊讶于设备构建版本的内存占用更小。
  • 精灵资源的源纹理设置为Sprite类型——额外的子对象导致移动端加载缓慢。

References

参考资料