面向新手的TextMeshPro使用说明

TextMeshPro 和 Text 效果上的不同

对比维度 TextMeshPro Text
文本显示效果 高分辨率渲染,支持子像素定位,文本清晰锐利 简单渲染,缩放时模糊、失真
富文本支持 支持复杂标签和自定义样式,功能丰富 支持简单的富文本功能
字体支持 动态字体生成,自定义字体图集,支持多语言和复杂脚本 静态字体支持,语言兼容性有限
高级排版功能 自动换行、字符间距、行间距、对齐方式等细节排版功能强大 仅支持简单的排版设置
特效支持 内置渐变、描边、阴影等丰富特效 需要手动实现特效,能力有限
性能 高效处理动态文本,支持材质合并优化渲染开销 性能较低,处理大量动态文本时容易卡顿
API 功能 丰富的 API,支持复杂样式控制和动态生成 API 功能少,只能满足简单文本操作
兼容性 需要额外的字体资源和材质设置,初次学习可能稍复杂 内置 Unity 功能,使用简单
多语言支持 支持阿拉伯语、中文、日文等复杂文字布局 对多语言支持有限,需手动调整
适用场景 高质量文本显示,大型项目,UI 动态文本 简单文本显示,小型项目,低复杂度 UI

TextMeshPro 和 Text 使用上的不同

最大的使用差别就一个, TMP 有字体库的概念. Text 组件直接引用字体文件, 而 TMP 则是引用以字体文件为基础制作而成的 TMP_Font Asset 资源.

如何生成 TMP_Font Asset 呢 ?

打开 Font Asset Creator 窗口, 放入字体文件, 选择会用到的字符集, 点击 Generate 即可生成. 如下图所示.

TMP 1

生成 TMP_Font Asset 的时候为什么 "慢", 而且是 "巨慢" ?

提问 : 为什么我生成的时候很慢很慢呢? 一次要 30 分钟甚至几小时!

回答 : 影响生成字符集时长的原因主要有 2 个

  1. 字符的数量

比如使用了常用汉字集这种几千字的集合, 大概需要几十秒, 下面是我电脑的数据: 4205 字, 可以看到, 生成时间耗费了 22 秒.

TMP 2

  1. Point Size 和 Padding 的设置

当要生成几千字的字体资源时, Point Size 和 Padding 不要设置为 Auto, 字符数量少时可以使用来快速找到合适的数值.

这个是让工具自动去调整 Point 以及 Padding 的大小, 这样工具会不断试错, 尝试一个值, 不行, 换下一个, 不行, 再换下一次, 还是不行, 再换 ... 如此往复 ... 因此 "慢" 是因为它生成了数次.

只要固定 Point 和 Padding 的大小, 它就会仅生成一次, 消耗的时间就很少了.

推荐一个常用的汉字集 : 跳转到 Github 汉字集

那么 Size 和 Padding 该设置多大呢 ?

先放一下 TextMeshPro 的官方手册 : TMP 4.0 手册

手册中是这样写的, 对于 512 的图集, padding 为 5 就够用了.

A padding of 5 is often fine for a 512x512 texture.

那么其他的分辨率下该设置多少呢? 你自己看着办 ... (多去尝试) 当然也可以参考我上面截图中的, 我是 8192 * 4096 的图集, 用的是 12, 感觉还好, 即使是 "加粗+描边" 效果下也很平滑, 至少肉眼看不出啥瑕疵来.

Padding 主要控制的就是字体显示效果, 原文是这么写的:

The larger the padding, the smoother the transition, which allows for higher-quality rendering and larger effects, like thick outlines.

意思就是这个值越大, 字体越平滑, 就越能支持更高质量的渲染和效果, 比如厚厚的描边.

至于 Point Size 嘛 ... 参考我的截图吧, 我的游戏中有时候会用到 50 号甚至 60 号的文字, 感觉 Point Size 设置为 72 已经挺极限了, 再小的话显示就出问题了.

画面缩小后文字有 "白底" ?

这个其实是 SP/PD Ratio 值过小导致的. SP/PD Ratio 数值就是 padding 和 point size 的比值, 用来描述各个字符之间空隙的大小, 空隙太小时便会出现白底的问题, 但是太大也不好, 浪费空间嘛.

网上的说法是, 推荐最大 10%, 最小 4%, 但是我实测发现基本低于 10% 就会出现白底了, 所以我推荐的值为 12% 左右, 太小出现白底, 太大浪费空间, 自己通过手调 Point Size 和 Padding 来调整吧.

这是别人的研究, 我也不确定文章会不会哪天就看不了了, 智障的 CSDN 会员! 且看且珍惜吧, 也不长, 主要意思就一个: SP/PD Ratio 值过小过导致白底, 我都总结了. 它的文章里面就是写了原因的推测, 也只是推测, 这里是原文: 文字白底问题探讨

玩家文本输入框怎么做呢 ? 因为我不可能提前预知玩家输入哪些字符呀 ?

是的, 我们确实无法预知, 所以这里就要用到之前从来没有提到的另一个概念了 : 动态字体.

我们之前创建的字体资源都是静态字体, 顾名思义, 静态字体的意思就是打包哪些字符就支持显示哪些字符, 没有打包的就不支持, 这也是为什么很多人一开始用 TMP 显示不了中文字符的原因.

而动态字体中, 初始是没有任何字符的, 它是现用现做, 因此性能上就会差一些, 但是好处也是毋庸置疑的, 它能支持字体文件中全部字符.

怎么做一个动态字体呢 ?

直接引用手册原文

Creating a dynamic font Asset
Empty font assets are dynamic by default. To create one:

From Unity's main menu, choose "Assets > Create > TextMeshPro > Font Asset" or press Ctrl/Cmd + Shift + F12.
To make an existing font Asset dynamic:

Select Asset and open it in the Inspector.

Set the Generation Settings > Atlas Population Mode property to Dynamic.

通过修改字体文件的材质属性实现了一个效果, 但是要实现另一个效果怎么办 ? 难道要再创建一份字体资源吗 ?

不需要再创建一份字体资源, 否则人都麻了... 只需要创建一份 Material Preset 即可, 如图操作

TMP 3

选中字体资源下的材质球, 仅选中即可, 然后点击 Inspector 面板上材质球的小菜单, 竖着的三个小点, 记得是材质球的菜单, 不是上面那个三个小点的菜单, 有两个, 千万别混了. 最后点击菜单中的 "Create Material Preset" 即可, 这样在 TextMeshPro 控件中的材质球选项处会自动多出选项供你选择.

彩色 emoji 字符怎么支持 ? 表情包怎么支持 ? 有哪些可用的富文本标签 ? 渐变效果怎么支持 ?

这些目前我也还没开始大规模使用, 就尝试使用了一下表情包和标签而已, 具体的请直接查阅文档, 文档巨详细.

color emoji 支持 (字符表情)

表情包支持 (图片表情)

富文本标签支持

Style Sheet 支持

颜色渐变效果支持

总结 : 首个项目的 TextMeshPro 的一般使用姿势 (后面的项目可以直接复用)

  1. 选择各个语种: 英文、日文、韩文、中文等要使用的字体, 可用即可, 后期再正式选择. 一般每种语种都要单独选择, 支持多个语种的字体一般除了主语种外的其他语种字符都不好看.

  2. 对各个字体文件创建动态字体资源, 直接使用动态的, 因为具体要用到哪些字符还没有完全确定, 静态的也不好做.

  3. 将动态字体中收集的字符进行分类: 英文、数字、符号、日文、韩文、中文、数学符号等等, 分别创建对应的 txt 文件.

  4. 选择一个主字体, 比如中文, 然后将 ASCII、日文、韩文 作为 CallBack 设置. 如果字母和数字想使用不同的字体, 可以在步骤 3 那里详细进行拆分, 分别设置 CallBack, 比如英文用 A 数字字体, 中文用 B 数字字体等.

  5. 记得 CallBack 的最后必须设置上一个多语种的动态字体, 推荐开源的阿里巴巴普惠体3.0, 尤其是需要玩家输入昵称或者显示外部文本的地方, 更是必须使用动态字体 : 阿里巴巴普惠体3.0

  6. 无穷, 无限, 积分等数学符号可以使用支持数学符号的字体解决 : 数学字符字体