UGUI的Text组件只提供了行间距的调整,而无法调整字与字之间的间隔.
UGUI Text 组件中的每个文字,是由两个网格组成,因而调整字间距,可以通过修改每个字的网格顶点位置来实现。上文提到的博文中,只实现了从左向右以第一个字的坐标为起点,依次增加字符宽度和间距,作为偏移量计算出后续每个字的位置。但是右对齐时,文本位置需要从每行最后一个字作为起始位置,依次向左计算偏移量;居中对齐时,需要以第一个字作为起始位置,依次向右计算偏移量,但需要额外减去半行长度,时整行居中。半行长度的计算,需要考虑字符数的奇偶,奇数个字符时,需要额外偏移0.5个字符宽度。 根据以上思路,调整原博文中的代码如下:
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();
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();
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 = 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
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?