Unity如何实现文本超过指定长度时自动缩字,不超过则自适应宽度

        在实际游戏开发工作,UI会给出如下图所示的需求,希望底框随文字长度变化,但又不能太长要限制在一定范围内,这时候又需要自动缩字

首先,我们要把底图的布局和文字的ContentSizeFilter组件挂载好

接下来上脚本,Text和TextMeshPro我分别写了适合各自的脚本,实现逻辑大差不差

思路的核心就是设置一个开始缩字的文本长度变量,例如文本宽度超过500时是多少个字符,以后超过这个字符就开始缩字,小于这个字符再变回来。如果单纯判断宽度再缩字,我们就再也无法将其变回来了

下面是代码,首先是用于Text组件的TextAutoSizer:

using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(Text))]
[ExecuteInEditMode]
public class TextAutoSizer : MonoBehaviour
{
    public float MaxWidth = 500f;
    private int autoSizeLength;  //文本多长时该缩字
    private string lastText = "";  //上一次更新时的文本
    private int maxFixSize;
    private const int minFixSize = 24;
    private Text textComponent;
    private RectTransform textRectTransform;
    private ContentSizeFitter contentSizeFitter = null;
    private void OnEnable()
    {
        textComponent = GetComponent<Text>();
        textRectTransform=textComponent.GetComponent<RectTransform>();
        maxFixSize = textComponent.fontSize;
        contentSizeFitter = GetComponent<ContentSizeFitter>();
    }

    private void Update()
    {
        if (textComponent.text != lastText)
        {
            lastText = textComponent.text;
            
            if (autoSizeLength == 0)
            {
                if (textRectTransform.rect.width > MaxWidth)
                {
                    autoSizeLength = textComponent.text.Length;
                    BestFix(true);
                }
                else
                {
                    BestFix(false);
                }
            }
            else
            {

                if (textComponent.text.Length > autoSizeLength)
                {
                    BestFix(true);
                }
                else
                {
                    BestFix(false);
                }
            }
        }
    }

    private void BestFix(bool isFit)
    {
        textComponent.resizeTextForBestFit = isFit;

        if (isFit)
        {
            textComponent.resizeTextMinSize = minFixSize;
            textComponent.resizeTextMaxSize = maxFixSize;

            textRectTransform.sizeDelta = new Vector2(MaxWidth, textRectTransform.sizeDelta.y);
        }

        if (contentSizeFitter)
        {
            contentSizeFitter.enabled = !isFit;
        }
    }
}

用于TextMeshPro组件的TMPAutoSizer:

using TMPro;
using UnityEngine;
using UnityEngine.UI;

[RequireComponent(typeof(TextMeshProUGUI))]
[ExecuteInEditMode]

public class TMPAutoSizer : MonoBehaviour
{
    public float MaxWidth = 500f;
    private int autoSizeLength;  //文本多长时该缩字
    private string lastText = "";  //上一次更新时的文本
    private float originalFontSize;  //最开始的字号
    private float maxFixSize;
    private const int minFixSize = 24;
    private TextMeshProUGUI textComponent;
    private RectTransform textRectTransform;
    private ContentSizeFitter contentSizeFitter = null;
    private void OnEnable()
    {
        textComponent = GetComponent<TextMeshProUGUI>();
        textRectTransform = textComponent.GetComponent<RectTransform>();
        originalFontSize = textComponent.fontSize;
        maxFixSize = textComponent.fontSize;
        contentSizeFitter = GetComponent<ContentSizeFitter>();
    }

    private void Update()
    {
        if (textComponent.text != lastText)
        {
            lastText = textComponent.text;

            if (autoSizeLength == 0)
            {
                if (textRectTransform.rect.width > MaxWidth)
                {
                    autoSizeLength = textComponent.text.Length;
                    BestFix(true);
                }
                else
                {
                    BestFix(false);
                }
            }
            else
            {

                if (textComponent.text.Length > autoSizeLength)
                {
                    BestFix(true);
                }
                else
                {
                    BestFix(false);
                }
            }
        }
    }

    private void BestFix(bool isFit)
    {
        textComponent.enableAutoSizing = isFit;

        if (isFit)
        {
            textComponent.fontSizeMin = minFixSize;
            textComponent.fontSizeMax = maxFixSize;

            textRectTransform.sizeDelta = new Vector2(MaxWidth, textRectTransform.sizeDelta.y);
        }
        else
        {
            textComponent.fontSize = originalFontSize;
        }

        if (contentSizeFitter)
        {
            contentSizeFitter.enabled = !isFit;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值