zoukankan      html  css  js  c++  java
  • unity实战 UGUI Text 间距和ContentSizeFitter组件的适配

    策划需求:支持text间距,并且要跟ContentSizeFitter的宽度适配适应

    网上查了一些博客,https://blog.csdn.net/ls9512/article/details/82980147 发现这篇博客内容有支持text间距,但是使用过程中发现如果再使用ContentSizeFitter组件的话,将不会适应ui的sizedelta宽度。

    然后查到了一个工具(虽然最后没用):TextMesh Pro 看起来功能挺多的,但是没有源码,都是dll。我没法进行修改。就放弃了。当前我使用的text是CustomFont,使用静态图片的,可以合图。对于策划还是ok的。

    大概解决方案,获取字符的宽度,使用组件LayoutElement,自己计算合适的preferredWidth值。

    对上面的代码进行了加工,直接贴代码,初版没有优化,自己可以修改:

    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    [AddComponentMenu("UI/Effects/TextSpacing")]
    public class TextSpacing : BaseMeshEffect
    {
        #region Struct
    
        public enum HorizontalAligmentType
        {
            Left,
            Center,
            Right
        }
    
        public class Line
        {
            // 起点索引
            public int StartVertexIndex { get { return _startVertexIndex; } }
            private int _startVertexIndex = 0;
    
            // 终点索引
            public int EndVertexIndex { get { return _endVertexIndex; } }
            private int _endVertexIndex = 0;
    
            // 该行占的点数目
            public int VertexCount { get { return _vertexCount; } }
            private int _vertexCount = 0;
    
            public Line(int startVertexIndex, int length)
            {
                _startVertexIndex = startVertexIndex;
                _endVertexIndex = length * 6 - 1 + startVertexIndex;
                _vertexCount = length * 6;
            }
        }
    
        #endregion
    
        public float Spacing = 1f;
    
        public override void ModifyMesh(VertexHelper vh)
        {
            if (!IsActive() || vh.currentVertCount == 0)
            {
                return;
            }
    
            var text = GetComponent<Text>();
    
            if (text == null)
            {
                Debug.LogError("Missing Text component");
                return;
            }
    
            // 水平对齐方式
            HorizontalAligmentType alignment;
            if (text.alignment == TextAnchor.LowerLeft || text.alignment == TextAnchor.MiddleLeft || text.alignment == TextAnchor.UpperLeft)
            {
                alignment = HorizontalAligmentType.Left;
            }
            else if (text.alignment == TextAnchor.LowerCenter || text.alignment == TextAnchor.MiddleCenter || text.alignment == TextAnchor.UpperCenter)
            {
                alignment = HorizontalAligmentType.Center;
            }
            else
            {
                alignment = HorizontalAligmentType.Right;
            }
    
            var vertexs = new List<UIVertex>();
            vh.GetUIVertexStream(vertexs);
            // var indexCount = vh.currentIndexCount;
    
            var lineTexts = text.text.Split('
    ');
    
            var lines = new Line[lineTexts.Length];
    
            // 根据lines数组中各个元素的长度计算每一行中第一个点的索引,每个字、字母、空母均占6个点
            for (var i = 0; i < lines.Length; i++)
            {
                // 除最后一行外,vertexs对于前面几行都有回车符占了6个点
                if (i == 0)
                {
                    lines[i] = new Line(0, lineTexts[i].Length + 1);
                }
                else if (i > 0 && i < lines.Length - 1)
                {
                    lines[i] = new Line(lines[i - 1].EndVertexIndex + 1, lineTexts[i].Length + 1);
                }
                else
                {
                    lines[i] = new Line(lines[i - 1].EndVertexIndex + 1, lineTexts[i].Length);
                }
            }
    
            UIVertex vt;
            float oldlen = 9999;//取最前最后的字符串偏移,适配sizedelta
            float lastlen = 9999;
            float oldrightlen = 9999;
            float lastrightlen = 9999;
            for (var i = 0; i < lines.Length; i++)
            {
                for (var j = lines[i].StartVertexIndex; j <= lines[i].EndVertexIndex; j++)
                {
                    if (j < 0 || j >= vertexs.Count)
                    {
                        continue;
                    }
    
                    vt = vertexs[j];
    
                    var charCount = lines[i].EndVertexIndex - lines[i].StartVertexIndex;
                    if (i == lines.Length - 1)
                    {
                        charCount += 6;
                    }
    
                    if (alignment == HorizontalAligmentType.Left)
                    {
                        oldlen = vt.position.x;
                        vt.position += new Vector3(Spacing * ((j - lines[i].StartVertexIndex) / 6), 0, 0);
                        lastlen = vt.position.x;
                    }
                    else if (alignment == HorizontalAligmentType.Right)
                    {
                        if (oldlen >= 9999){
                            oldlen = vt.position.x;
                        }
                        oldrightlen = vt.position.x;
                        vt.position += new Vector3(Spacing * (-(charCount - j + lines[i].StartVertexIndex) / 6 + 1), 0, 0);
                        if (lastlen >= 9999){
                            lastlen = vt.position.x;
                        }
                        lastrightlen = vt.position.x;
                    }
                    else if (alignment == HorizontalAligmentType.Center)
                    {
                        if (oldlen >= 9999){
                            oldlen = vt.position.x;
                        }
                        oldrightlen = vt.position.x;
                        var offset = (charCount / 6) % 2 == 0 ? 0.5f : 0f;
                        vt.position += new Vector3(Spacing * ((j - lines[i].StartVertexIndex) / 6 - charCount / 12 + offset), 0, 0);
                        if (lastlen >= 9999){
                            lastlen = vt.position.x;
                        }
                        lastrightlen = vt.position.x;
                    }
    
                    vertexs[j] = vt;
                    // 以下注意点与索引的对应关系
                    if (j % 6 <= 2)
                    {
                        vh.SetUIVertex(vt, (j / 6) * 4 + j % 6);
                    }
    
                    if (j % 6 == 4)
                    {
                        vh.SetUIVertex(vt, (j / 6) * 4 + j % 6 - 1);
                    }
                }
            }
            string message = text.text;
            int totalLength = 0;
            Font myFont = text.font;
            for(int i = 0; i < message.Length; i++){
                Characterinfo ch;
                myFont.GetCharacterInfo(message[i], out ch);
                totalLength += ch.advance;
            }
            LayoutElement le = GetComponent<LayoutElement >();
            if (le != null){
                le.preferredWidth = totalLength +(lastlen - oldlen)+(lastrightlen - oldrightlen);
            }
        }
    }
                                                                                           
  • 相关阅读:
    内置对象,监听器,过滤器
    20169201 使用Metaspoit攻击MS08-067实验
    20169201 2016-2017-2《网络攻防》课程总结
    20169201 2016-2017-2 《网络攻防》第十四周作业
    20169201 2016-2017-2 《网络攻防实践》第11周学习总结
    20169201 2016-2017-2 《移动平台开发实践》第10周学习总结
    20169201 2016-2017-2 《网络攻防实践》第10周学习总结
    20169201 实验三 敏捷开发与XP实践报告
    20169201 2016-2017-2 《网络攻防实践》 实验二
    20169201 2016-2017-2 实验一 网络攻防实验环境的搭建与测试
  • 原文地址:https://www.cnblogs.com/leilei-weapon/p/10335623.html
Copyright © 2011-2022 走看看