Unity reduces font size when implementing Text BestFit text hyperbox

foreword

Because of the multi-language adaptive function, Unity's own BestFit will automatically reduce the font after more than one line. The desired effect is to reduce the font after the text is full, so the OnPopulateMesh drawing part needs to be rewritten.

code

using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;

public class NewText : Text
{
    
    
        #region 实现超框时再缩小字体,适配多语言
        /// <summary>
        /// 当前可见的文字行数
        /// </summary>
        public int VisibleLines {
    
     get; private set; }

        private void _UseFitSettings()
        {
    
    
            TextGenerationSettings settings = GetGenerationSettings(rectTransform.rect.size);
            settings.resizeTextForBestFit = false;

            if (!resizeTextForBestFit)
            {
    
    
                cachedTextGenerator.PopulateWithErrors(text, settings, gameObject);
                return;
            }

            int minSize = resizeTextMinSize;
            int txtLen = text.Length;
            for (int i = resizeTextMaxSize; i >= minSize; --i)
            {
    
    
                settings.fontSize = i;
                cachedTextGenerator.PopulateWithErrors(text, settings, gameObject);
                if (cachedTextGenerator.characterCountVisible == txtLen) break;
            }
        }

        private readonly UIVertex[] _tmpVerts = new UIVertex[4];
        protected override void OnPopulateMesh(VertexHelper toFill)
        {
    
    
            if (null == font) return;

            m_DisableFontTextureRebuiltCallback = true;
            _UseFitSettings();

            // Apply the offset to the vertices
            IList<UIVertex> verts = cachedTextGenerator.verts;
            float unitsPerPixel = 1 / pixelsPerUnit;
            int vertCount = verts.Count;

            // We have no verts to process just return (case 1037923)
            if (vertCount <= 0)
            {
    
    
                toFill.Clear();
                return;
            }

            Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel;
            roundingOffset = PixelAdjustPoint(roundingOffset) - roundingOffset;
            toFill.Clear();
            if (roundingOffset != Vector2.zero)
            {
    
    
                for (int i = 0; i < vertCount; ++i)
                {
    
    
                    int tempVertsIndex = i & 3;
                    _tmpVerts[tempVertsIndex] = verts[i];
                    _tmpVerts[tempVertsIndex].position *= unitsPerPixel;
                    _tmpVerts[tempVertsIndex].position.x += roundingOffset.x;
                    _tmpVerts[tempVertsIndex].position.y += roundingOffset.y;
                    if (tempVertsIndex == 3)
                        toFill.AddUIVertexQuad(_tmpVerts);
                }
            }
            else
            {
    
    
                for (int i = 0; i < vertCount; ++i)
                {
    
    
                    int tempVertsIndex = i & 3;
                    _tmpVerts[tempVertsIndex] = verts[i];
                    _tmpVerts[tempVertsIndex].position *= unitsPerPixel;
                    if (tempVertsIndex == 3)
                        toFill.AddUIVertexQuad(_tmpVerts);
                }
            }

            m_DisableFontTextureRebuiltCallback = false;
            VisibleLines = cachedTextGenerator.lineCount;
        }
        #endregion
}

Check BestFit.

Guess you like

Origin blog.csdn.net/qq_39162826/article/details/127068201