mcpField
O
optimize-text-mesh-pro

optimize-text-mesh-pro

github.com/unity-technologies开发58154 次安装6 天前更新
代码仓库

关于 optimize-text-mesh-pro

为 Unity TextMeshPro 项目提供诊断与优化指导,面向处理字体、性能和构建问题的开发者。内容按症状组织,涵盖图集内存、文字呈现、布局及多语言构建。

主要功能

  1. 01按症状定位 TMP 问题
  2. 02配置静态字体与动态回退
  3. 03优化图集采样与内存
  4. 04降低文本更新和 Canvas 重建开销
  5. 05处理拉丁文与 CJK 对齐
  6. 06使用材质预设管理字形样式

适用场景

  1. 01排查动态字体图集内存膨胀
  2. 02改善大字号文字的模糊边缘
  3. 03减少计数器更新引发的 CPU 峰值
  4. 04缩减多语言移动端构建体积

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/unity-technologies/unity-agent-plugin --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 文字未对齐,请引导他们完成以下步骤:

  1. Window -> TextMeshPro -> Settings -> Import TMP Example & Extras(每个项目只需执行一次)。
  2. 将 TMP_TextInfoDebugTool 组件添加到显示未对齐文本的 TextMeshPro 对象。
  3. 启用 ShowLines 开关——升部线、降部线和基线将以叠加层形式显示。
  4. 混排拉丁文字和 CJK 文字;如果这些线彼此偏离,调整 TMP Font Asset 上的 ascender/descender,直到对齐。

注意:据观察,在某些项目布局中导入 TMP Examples & Extras 会导致无限导入循环。如果发生这种情况,请关闭 Unity 并重新打开——第二次尝试时即可完成导入。


材质预设

如果用户需要同一字体的多种样式(斜体、粗体、描边、辉光),建议使用材质预设,而不是复制字体资源。预设共享同一字体纹理,但会覆盖着色器参数。

创建方法:

  1. 选择一个 TMP Text GameObject。
  2. 在 Inspector 中找到 Material 部分。
  3. 右键单击 Material 标题 -> Create Material Preset。
  4. 重命名新材质并调整设置。
  5. 在 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 的系统字体:

平台推荐的系统字体
AndroidNotoSans(广泛覆盖中文、日文和韩文字形)。
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——额外的子对象会拖慢移动设备上的加载速度。

参考资料

评论

支持 Markdown