如何避免更新TextMeshProUGUI文本后顶点颜色被重置?
解决TextMeshProUGUI逐字符打印时顶点颜色被重置的问题
方案1:用TMP原生富文本标签替代手动顶点修改
既然你已经能识别<#A63F3F>这类颜色标签,直接把标签嵌入到逐字符输出的文本里就行。TMP本身支持富文本渲染,完全不需要手动修改顶点:
- 协程遍历输入文本时,遇到颜色标签就完整截取整个标签(比如从
<#到>的部分),拼接到当前输出文本中; - 后续输出的字符会自动继承该标签的颜色,直到遇到下一个颜色标签或重置标签(如
<color=white>); - 这种方式性能最优,因为是TMP原生逻辑,没有额外的顶点操作开销。
方案2:用SetCharArray追加字符,仅更新新增顶点颜色
如果必须手动修改顶点颜色,别直接赋值output.text,改用SetCharArray追加字符,避免全量重置顶点数据:
- 初始化时将
output.text设为空,提前获取textInfo引用:TMP_Text output = GetComponent<TextMeshProUGUI>(); output.text = ""; TMP_TextInfo textInfo = output.textInfo; - 协程中每次新增字符时,用
SetCharArray追加,而非替换整个文本:// i为当前要追加的字符索引 output.SetCharArray(i, i, new char[]{input[i]}); - 获取新增字符的顶点信息,修改对应顶点颜色,最后只更新颜色数据:
TMP_CharacterInfo charInfo = textInfo.characterInfo[i]; if (!charInfo.isVisible) continue; // 每个字符对应4个顶点,获取顶点索引范围 int vertexIndex = charInfo.vertexIndex; Color32 targetColor = /* 你解析到的目标颜色 */; TMP_MeshInfo[] meshInfos = textInfo.meshInfo; // 修改4个顶点的颜色 meshInfos[0].colors32[vertexIndex] = targetColor; meshInfos[0].colors32[vertexIndex + 1] = targetColor; meshInfos[0].colors32[vertexIndex + 2] = targetColor; meshInfos[0].colors32[vertexIndex + 3] = targetColor; // 只更新颜色数据,避免全量刷新 output.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
- 注意:要确保字符索引和顶点索引的对应关系,同时处理字符不可见的情况(比如空格)。
方案3:继承TMP_Text自定义渲染逻辑(进阶)
如果需要更复杂的颜色控制,可以继承TMP_Text重写OnRenderObject方法,在其中自定义顶点颜色的持久化逻辑,避免文本更新时重置颜色。不过这种方式需要熟悉TMP的底层渲染流程,适合有一定源码基础的开发者。
关键注意点
- 直接赋值
output.text会触发TMP的全量布局重建和顶点重置,这是颜色丢失的核心原因,要尽量避免; - 优先选择方案1,因为是原生支持的最优解,性能和维护成本都最低。
内容的提问来源于stack exchange,提问作者Hleb Butkevich
相关产品推荐
相关产品推荐

