You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity ScrollView使用TextMeshPro时无法正常滚动到底部问题

TextMeshPro 替换原生Text后滚动区域无法到达底部的解决方法

这个问题的核心原因是TMP的文本布局计算和UI系统的Content尺寸刷新不同步:原生Text组件会在UI重建时同步返回正确的首选高度,而TMP因为支持富文本、动态字体、字符按需加载,其实际渲染高度的计算默认延迟1~2帧完成,ScrollRect在初始化时拿到的是未刷新完成的错误Content高度,可滚动范围比实际内容小,就会出现滚到一半被挡住、强制拖到底松开自动回弹的现象。

按以下顺序排查修复即可:

  • 检查Content节点的布局组件配置
    挂载在Content上的Vertical Layout Group需要取消勾选Child Force Expand > Vertical选项,Child Alignment设为顶部对齐;挂载的Content Size Fitter垂直适配选择Preferred Size,不要选Unconstrained或者Min Size。
  • 强制刷新布局,解决TMP延迟计算问题
    不要在Awake/Start生命周期里直接读取TMP的高度,这时候TMP还没完成文本排版,读到的值是错的。在界面初始化、文本赋值完成后,调用以下代码强制刷新:
    // 强制TMP立刻完成文本网格计算,拿到正确的首选高度
    tmpText.ForceMeshUpdate();
    // 强制重建Content节点下所有布局,更新ScrollRect的可滚动边界
    LayoutRebuilder.ForceRebuildLayoutImmediate(contentRectTransform);
    
    如果是动态赋值文本、或者加载了远程字体/表情图集,延迟一帧再刷新一次更稳妥:
    // 调用完上面的代码后加这行
    StartCoroutine(DelayedRefreshLayout());
    
    private IEnumerator DelayedRefreshLayout()
    {
        // 等一帧等所有渲染资源加载完成
        yield return null;
        tmpText.ForceMeshUpdate();
        LayoutRebuilder.ForceRebuildLayoutImmediate(contentRectTransform);
        // 需要默认滚动到顶部可以加下面这行
        scrollRect.verticalNormalizedPosition = 1;
    }
    
  • 检查TMP组件自身配置
    • TMP的Overflow属性要设为Overflow,哪怕肉眼看文本没有截断,Ellipsis/Truncate模式会限制TMP返回的首选高度值,导致Content尺寸计算错误
    • TMP节点的RectTransform锚点设为顶部拉伸模式(Anchor Min = (0,1),Anchor Max = (1,1),Pivot = (0.5,1)),锚点位置不对会导致布局组件计算高度时出现固定偏移,底部永远留一截滚不到
  • 不要随意修改ScrollRect的Movement Type
    不用为了绕过回弹问题把Elastic模式改成Unrestricted,那样会出现内容滚出视口、没有边界限制的问题,前面的布局刷新逻辑生效后,Elastic模式的回弹边界会自动和实际内容底部对齐。

验证方法:运行状态下选中Content节点,查看RectTransform组件的Height值,和TMP组件上显示的Preferred Height值做对比,两个数值完全相等时滚动范围就是正确的;如果Content高度比TMP的Preferred Height小,说明布局刷新没有执行到位。

内容的提问来源于stack exchange,提问作者Mr. Tacio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:03:28