Unity中如何获取TextMeshPro的每行字符数及可视区域行数?
Unity TextMeshPro 核心需求解决方案
一、获取每行的字符数量
直接借助TextMeshPro的TextInfo属性,其内置的lineInfo数组存储了每一行的索引信息,通过firstCharacterIndex与lastCharacterIndex的差值即可计算出对应行的字符数:
using TMPro; using UnityEngine; public class TMPLineCharCounter : MonoBehaviour { public TextMeshProUGUI targetText; void CalculateEachLineCharCount() { if (targetText == null) return; targetText.ForceMeshUpdate(); // 强制更新文本网格,避免数据滞后 TMP_TextInfo textInfo = targetText.textInfo; for (int i = 0; i < textInfo.lineCount; i++) { TMP_LineInfo lineInfo = textInfo.lineInfo[i]; // 跳过空行(空行的首尾索引为-1) if (lineInfo.firstCharacterIndex == -1) continue; int charCount = lineInfo.lastCharacterIndex - lineInfo.firstCharacterIndex + 1; Debug.Log($"第{i+1}行字符数:{charCount}"); } } }
注意:文本动态修改后必须调用ForceMeshUpdate(),否则会获取到旧的行数据。
二、滚动视图中获取可视区域内的行数
结合ScrollRect的视口(Viewport)与TextMeshPro每行的位置信息,将行的世界坐标转换为视口本地坐标后,判断是否处于视口范围内即可:
using TMPro; using UnityEngine; using UnityEngine.UI; public class TMPVisibleLineDetector : MonoBehaviour { public ScrollRect scrollRect; public TextMeshProUGUI targetText; int GetCurrentVisibleLineCount() { if (scrollRect == null || targetText == null) return 0; targetText.ForceMeshUpdate(); TMP_TextInfo textInfo = targetText.textInfo; RectTransform viewportRect = scrollRect.viewport; RectTransform textRect = targetText.rectTransform; int visibleLineCount = 0; for (int i = 0; i < textInfo.lineCount; i++) { TMP_LineInfo lineInfo = textInfo.lineInfo[i]; if (lineInfo.firstCharacterIndex == -1) continue; // 转换行的顶部、底部坐标到视口本地坐标系 Vector3 lineTopWorld = textRect.TransformPoint(lineInfo.lineExtents.max); Vector3 lineTopLocal = viewportRect.InverseTransformPoint(lineTopWorld); Vector3 lineBottomWorld = textRect.TransformPoint(lineInfo.lineExtents.min); Vector3 lineBottomLocal = viewportRect.InverseTransformPoint(lineBottomWorld); // 判断行是否与视口重叠:行底部未超出视口顶部,且行顶部未超出视口底部 bool isVisible = lineBottomLocal.y < viewportRect.rect.height && lineTopLocal.y > 0; if (isVisible) visibleLineCount++; } return visibleLineCount; } // 绑定到ScrollRect的OnValueChanged事件,滚动时实时计算 void OnScrollUpdated() { int visibleLines = GetCurrentVisibleLineCount(); Debug.Log($"当前可视行数:{visibleLines}"); } }
说明:
- 若为水平滚动视图,只需将判断逻辑中的
y轴替换为x轴即可。 - 视口坐标系以左下角为原点,所以判断条件需确保行的有效区域落在视口范围内。
内容的提问来源于stack exchange,提问作者fr000g
相关产品推荐
相关产品推荐

