Unity Text修改字间距

简介: 本文介绍了两种实现字间距调整的方法。第一种方法直接通过修改顶点位置实现字间距调整,代码简洁但换行时效果不佳。第二种方法引入了`Line`结构和对齐方式(左、中、右),能够处理多行文本并支持不同对齐方式,更加灵活和通用。两种方法均基于Unity的`BaseMeshEffect`类,通过重写`ModifyMesh`方法来调整UI文本的字间距。最终运行测试可验证效果。

第一种方法
换行就会失去效果
代码如下:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;
using System.Collections.Generic;
/// <summary>
/// 字间距
/// </summary>
public class TextSpacing : BaseMeshEffect
{
    public float _textSpacing = 1f;

    public override void ModifyMesh(VertexHelper vh)
    {
        if (!IsActive() || vh.currentVertCount == 0)
        {
            return;
        }
        List<UIVertex> vertexs = new List<UIVertex>();
        vh.GetUIVertexStream(vertexs);
        int indexCount = vh.currentIndexCount;
        UIVertex vt;
        for (int i = 6; i < indexCount; i++)
        {
            //第一个字不用改变位置
            vt = vertexs[i];
            vt.position += new Vector3(_textSpacing * (i / 6), 0, 0);
            vertexs[i] = vt;
            //以下注意点与索引的对应关系
            if (i % 6 <= 2)
            {
                vh.SetUIVertex(vt, (i / 6) * 4 + i % 6);
            }
            if (i % 6 == 4)
            {
                vh.SetUIVertex(vt, (i / 6) * 4 + i % 6 - 1);
            }
        }
    }
}

第二种实现方法

代码如下:

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

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('\n');

        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;

        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)
                {
                    vt.position += new Vector3(Spacing * ((j - lines[i].StartVertexIndex) / 6), 0, 0);
                }
                else if (alignment == HorizontalAligmentType.Right)
                {
                    vt.position += new Vector3(Spacing * (-(charCount - j + lines[i].StartVertexIndex) / 6 + 1), 0, 0);
                }
                else if (alignment == HorizontalAligmentType.Center)
                {
                    var offset = (charCount / 6) % 2 == 0 ? 0.5f : 0f;
                    vt.position += new Vector3(Spacing * ((j - lines[i].StartVertexIndex) / 6 - charCount / 12 + offset), 0, 0);
                }

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

最后运行测试即可

相关文章
Winform中Textbox、NumericUpDown等修改高度,禁止输入数字或内容的实现
Winform中的Textbox、NumericUpDown控件通常在单行的情况下,无法直接通过`Height`属性修改高度,但很多时候我们需要调整其高度,使其显示的更加合理,主要介绍三种方法...
2609 0
|
9月前
|
C++
[Qt5&控件] Label控件显示文本内容(字符串和整数)
[Qt5&控件] Label控件显示文本内容(字符串和整数)
174 0
[Qt5&控件] Label控件显示文本内容(字符串和整数)
|
前端开发 数据安全/隐私保护
CSS去掉input框里面的默认字体颜色
CSS去掉input框里面的默认字体颜色
159 1
layUI table 内容超出宽度怎么换行显示,而不是显示省略号
layUI table 内容超出宽度怎么换行显示,而不是显示省略号
484 0
Cocos Creator3.8 项目实战(三)去除scrollview背景色和label 对齐方式设置无效问题解决
Cocos Creator3.8 项目实战(三)去除scrollview背景色和label 对齐方式设置无效问题解决
167 0
|
前端开发
css文字选中添加背景色改变字体颜色--三角号demo效果示例(整理)
css文字选中添加背景色改变字体颜色--三角号demo效果示例(整理)
|
前端开发 测试技术
Easyui datagrid 设置内容超过单元格宽度时自动换行显示
Easyui datagrid 设置内容超过单元格宽度时自动换行显示
451 0
|
Web App开发 前端开发
去掉谷歌默认的input textarea边框样式
谷歌浏览器Chrome基于WebKit开源浏览器引擎,自然能够通过相关的一切方法自定义设置浏览器的默认状态。谷歌浏览器Chrome安装之后,大家应该都留意到所有的表单都会添加黄色边框特效。在某些时候这些特效还是很不错的,但是当网站本身就已经对于表单样式有一定的设计时,这种默认表单样式就会让人觉得套样了!
179 0
|
程序员 API iOS开发
iOS开发:字符串设置指定内容的文字颜色、文字大小、文字字体类型
在iOS开发过程中,会有一些为了提高APP的视觉效果而设置的特别一点的效果,比如一行文字需要自定义不同的颜色和文字大小,这就用到通过富文本来设置字符串的颜色、大小和文字类型。这篇博文我打算只介绍怎么设置指定内容的一些文字属性设置,如果之前看过我写的博文,就会发现有一篇类似介绍通过富文本来设置字符串内容的博文,但是那篇是综合性的,包括介绍button的,以及UItextfield的设置,所以在这里我只介绍怎么设置字符串指定位置的一些自定义设置的方法,如有不妥之处,欢迎指正。
635 0
|
移动开发 前端开发 HTML5
web前端学习(二)——HTML5的标题、段落、链接、注释、换行、插入水平线及对齐与缩进相关设置
web前端学习(二)——HTML5的标题、段落、链接、注释、换行、插入水平线及对齐与缩进相关设置
web前端学习(二)——HTML5的标题、段落、链接、注释、换行、插入水平线及对齐与缩进相关设置