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;
}
}