Unity TMPro实现文本框自动随文本内容伸缩

2025.3.7更了一个不用写代码的方法,不要看这个啦太复杂了

Unity TMPro实现文本框自动随文本内容伸缩-CSDN博客


主要用于给会变化的文本做一个背景板

思路如下:

1、背景为父物体,带有tmp的物体为子物体

我这里的背景是默认image,用其他的UI组件当背景也可以

2、给父物体挂上Horizontal Layout Group和Content Size Fitter

Content Size Fitter的Horizontal Fit 配置Preferred Size可以让子物体rect 宽度拉伸带动父物体宽度拉伸,Vertical则是高度拉伸带动父物体高度拉伸

 这部分来源于unity官方文档:使 UI 元素适应其内容的大小 - Unity 手册

 PS.这个Child Force Expand是默认勾选的,但是我自己尝试后发现勾和不勾效果完全相同,所以取消了勾选,,感兴趣的小伙伴可以看看手册再研究研究

3、现在我们尝试去拖动子物体的矩形框,发现子物体的宽度变换已经可以带动父物体的宽度变换了,但是现在问题来了,unity本身的TMP组件只有AutoSize只能实现TMP Text的字号随着文本内容的变化而自动调整,不能变换其矩形外框的长宽。所以我们需要写一个脚本来让它随文字长度变换矩形宽度

using UnityEngine;
using TMPro;

public class AdjustTMProSizeByText : MonoBehaviour
{
    private TMP_Text tmpText;

    private RectTransform rectTransform;

    

    void Start()
    {
 
        if (tmpText == null)
        {
            
            tmpText = GetComponent<TMP_Text>();
        }

        rectTransform = GetComponent<RectTransform>();

        UpdateSizeByText();
    }

    void Update()
    {
        // 在Update中实时更新TMP Text的大小
        UpdateSizeByText();
    }

    public void UpdateSizeByText()
    {
        if (tmpText != null && rectTransform != null)
        {
           

            // 获取TMP Text的最佳大小,根据字数和其他文本样式来计算
            Vector2 preferredSize = tmpText.GetPreferredValues(tmpText.text);

            // 调整矩形变换(RectTransform)的大小以适应文本内容的长度
            rectTransform.sizeDelta = preferredSize;
        }
    }
}

将它挂在有文本的子物体上即可实时更新文本框宽度(考虑到性能建议还是注释掉update,在更新文字内容的脚本中调用该脚本的方法UpdateSizeByText())

4、运行后就能查看效果啦


后面试了一下发现unity这个组件对PreferredSize的计算非常迷幻,会出现需要子物体变化超过一定幅度才跟着变换的情况(具有偶然性,没出现这种情况的小伙伴不用看后面了)

因此换一个思路,既然前面已经能用代码根据文本内容调整子物体矩形变换了,为什么不直接在此基础上将这一合适尺寸传给作为背景的父物体呢?(这样写的话就不需要挂上面提到的两个组件了)

主要的改动是给方法UpdateSizeByText()加上返回值,然后写一个代码调用该方法控制父物体矩形变换即可(注意将子物体的锚点锚定,这样不会移位)

修改代码如下

using UnityEngine;
using TMPro;

public class AdjustTMProSizeByText : MonoBehaviour
{
//这个脚本仍应挂到有文本的子物体上
    private TMP_Text tmpText;

    private RectTransform rectTransform;

    void Start()
    {
 
        if (tmpText == null)
        {
            
            tmpText = GetComponent<TMP_Text>();
        }
        
        rectTransform = GetComponent<RectTransform>();
        
        UpdateSizeByText();
    }



    public Vector2 UpdateSizeByText()
    {

        if (tmpText == null)
        {
          
            tmpText = GetComponent<TMP_Text>();
            rectTransform = GetComponent<RectTransform>();
        }
    
        // 获取TMP Text的最佳大小,根据字数和其他文本样式来计算
        Vector2 preferredSize = tmpText.GetPreferredValues(tmpText.text);//主要问题:没算行距
        
        preferredSize.x += 251;//宽度拉伸
      
        //把行距加上
        int lineCount = CountNewLinesInText(tmpText.text);
        float lineSpacing = 35;
        preferredSize.y += lineSpacing * lineCount;
       
        // 调整矩形变换(RectTransform)的大小以适应文本内容的长度
        rectTransform.sizeDelta = preferredSize;

         
        return preferredSize;//把矩形参数传出去
       

    }
    private int CountNewLinesInText(string text)
    {
        int newLineCount = 0;
        for (int i = 0; i < text.Length; i++)
        {
            if (text[i] == '\n')
            {
                newLineCount++;
            }
        }
        return newLineCount;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值