using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;
[DisallowMultipleComponent]
[AddComponentMenu("UI/ToolKit/TextColumnSpacing")]
public class TextColumnSpacing : BaseMeshEffect
{
public float columnSpacing = 0f;
private float _alignmentFactor = 0f;
public override void ModifyMesh(VertexHelper toFill)
{
if (columnSpacing == 0)
return;
if (!IsActive() || toFill.currentVertCount == 0)
return;
Text textCmp = GetComponent<Text>();
if (textCmp == null)
{
Debug.LogError("Missing Text component");
return;
}
_alignmentFactor = GetAlignmentFactor(textCmp.alignment);
IList<UILineInfo> lineInfos = textCmp.cachedTextGenerator.lines;
for (int i = 0; i < lineInfos.Count; i++)
{
UILineInfo line = lineInfos[i];
if (i + 1 < lineInfos.Count)
{
int current = 0;
int lineLength = lineInfos[i + 1].startCharIdx;
for (int j = line.startCharIdx; j < lineLength; j++)
{
ModifyText(toFill, j, current++, lineLength);
}
}
else if (i + 1 == lineInfos.Count) // The last line.
{
int current = 0;
int lineLength = textCmp.cachedTextGenerator.characterCountVisible;
for (int j = line.startCharIdx; j < lineLength; j++)
{
ModifyText(toFill, j, current++, lineLength);
}
}
}
}
void ModifyText(VertexHelper helper, int i, int charYPos, int lineLength)
{
float percent = (charYPos * 1.0f) / (lineLength * 1.0f);
int factor = 0;
if (percent < _alignmentFactor)
{
factor = -1;
}
else if(percent > _alignmentFactor)
{
factor = 1;
}
float lineOffset = charYPos * columnSpacing * factor;
Vector3 offset = Vector3.right * ((columnSpacing * charYPos) + lineOffset);
for (int j = 0; j < 4; j++)
{
UIVertex vertex = new UIVertex();
helper.PopulateUIVertex(ref vertex, i * 4 + j);
vertex.position += offset;
helper.SetUIVertex(vertex, i * 4 + j);
}
}
float GetAlignmentFactor(TextAnchor alignment)
{
switch (alignment)
{
default:
Debug.LogError("Invalid Convert Here!");
return 0;
case TextAnchor.UpperLeft:
case TextAnchor.MiddleLeft:
case TextAnchor.LowerLeft:
return 0;
case TextAnchor.UpperCenter:
case TextAnchor.MiddleCenter:
case TextAnchor.LowerCenter:
return .5f;
case TextAnchor.UpperRight:
case TextAnchor.MiddleRight:
case TextAnchor.LowerRight:
return 1f;
}
}
}
修正
using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;
using System.Text.RegularExpressions;
[DisallowMultipleComponent]
[AddComponentMenu("UI/ToolKit/TextSpacingPro")]
public class TextSpacingPro : BaseMeshEffect
{
public float _textSpacing = 1f;
//Rich Text Regex Patterns
private const string m_RichTextRegexPatterns = @"<b>|</b>|<i>|</i>|<size=.*?>|</size>|<Size=.*?>|</Size>|<color=.*?>|</color>|<Color=.*?>|</Color>|<material=.*?>|</material>";
public override void ModifyMesh(VertexHelper toFill)
{
if (_textSpacing == 0)
return;
if (!IsActive() || toFill.currentVertCount == 0)
return;
Text textCmp = GetComponent<Text>();
if (textCmp == null)
{
Debug.LogError("Missing Text component");
return;
}
List<UIVertex> vertexes = new List<UIVertex>();
toFill.GetUIVertexStream(vertexes);
List<List<int>> linesVertexStartIndexes = GetLinesVertexStartIndexes(textCmp);
float alignmentFactor = GetAlignmentFactor(textCmp.alignment);
for (int i = 0; i < linesVertexStartIndexes.Count; i++)
{
//行偏移(左中右)
float lineOffset = (linesVertexStartIndexes[i].Count - 1) * _textSpacing * alignmentFactor;
for (int j = 0; j < linesVertexStartIndexes[i].Count; j++)
{
int vertexStartIndex = linesVertexStartIndexes[i][j];
Vector3 offset = Vector3.right * ((_textSpacing * j) - lineOffset);
//对每个有效字体的六个顶点偏移
AddVertexOffset(vertexes, vertexStartIndex + 0, offset);
AddVertexOffset(vertexes, vertexStartIndex + 1, offset);
AddVertexOffset(vertexes, vertexStartIndex + 2, offset);
AddVertexOffset(vertexes, vertexStartIndex + 3, offset);
AddVertexOffset(vertexes, vertexStartIndex + 4, offset);
AddVertexOffset(vertexes, vertexStartIndex + 5, offset);
}
}
toFill.Clear();
toFill.AddUIVertexTriangleStream(vertexes);
}
//获取有效的初始顶点
List<List<int>> GetLinesVertexStartIndexes(Text textCmp)
{
List<List<int>> linesVertexIndexes = new List<List<int>>();
IList<UILineInfo> lineInfos = textCmp.cachedTextGenerator.lines;
int startIndex = -1;
for(int i=0;i<lineInfos.Count;i++)
{
List<int> lineVertexStartIndex = new List<int>();
int lineStart = lineInfos[i].startCharIdx;
int lineLength = (i < lineInfos.Count - 1) ? lineInfos[i + 1].startCharIdx - lineInfos[i].startCharIdx:textCmp.text.Length - lineInfos[i].startCharIdx;
//Rich Text根据正则表达式获取需要忽略的初始顶点
List<int> ignoreIndexes = new List<int>();
if (textCmp.supportRichText)
{
string line = textCmp.text.Substring(lineStart, lineLength);
var matchCollection = Regex.Matches(line, m_RichTextRegexPatterns);
foreach (Match matchTag in matchCollection)
{
for(int j=0; j<matchTag.Length; j++)
ignoreIndexes.Add(matchTag.Index + j);
}
}
for (int j = 0; j < lineLength; j++)
if (ignoreIndexes.Count == 0 || !ignoreIndexes.Contains(j))
lineVertexStartIndex.Add((++startIndex)*6);
// for (int j = 0; j < lineLength; j++)
// if (ignoreIndexes.Count == 0 || !ignoreIndexes.Contains(j))
// lineVertexStartIndex.Add((lineStart+j)*6);
linesVertexIndexes.Add(lineVertexStartIndex);
}
return linesVertexIndexes;
}
//对顶点进行偏移
void AddVertexOffset(List<UIVertex> vertexes,int index,Vector3 offset)
{
if (index >= vertexes.Count)
{
Debug.Log(index);
}
UIVertex vertex = vertexes[index];
vertex.position += offset;
vertexes[index] = vertex;
}
//获取行偏移比例参数
float GetAlignmentFactor(TextAnchor alignment)
{
switch (alignment)
{
default:
Debug.LogError("Invalid Convertions Here!");
return 0;
case TextAnchor.UpperLeft:
case TextAnchor.MiddleLeft:
case TextAnchor.LowerLeft:
return 0;
case TextAnchor.UpperCenter:
case TextAnchor.MiddleCenter:
case TextAnchor.LowerCenter:
return .5f;
case TextAnchor.UpperRight:
case TextAnchor.MiddleRight:
case TextAnchor.LowerRight:
return 1f;
}
}
}
TextSpacingPro
using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;
using System.Text.RegularExpressions;
[AddComponentMenu("UI/Effects/TextSpacingPro")]
public class TextSpacingPro : BaseMeshEffect
{
public float _textSpacing = 1f;
//正则表达式参数
private const string m_RichTextRegexPatterns = @"<b>|</b>|<i>|</i>|<size=.*?>|</size>|<Size=.*?>|</Size>|<color=.*?>|</color>|<Color=.*?>|</Color>|<material=.*?>|</material>";
public override void ModifyMesh(VertexHelper toFill)
{
if (_textSpacing == 0)
return;
if (!IsActive() || toFill.currentVertCount == 0)
return;
Text textCmp = GetComponent<Text>();
if (textCmp == null)
{
Debug.LogError("Missing Text component");
return;
}
List<UIVertex> vertexes = new List<UIVertex>();
toFill.GetUIVertexStream(vertexes);
List<List<int>> linesVertexStartIndexes = GetLinesVertexStartIndexes(textCmp);
float alignmentFactor = GetAlignmentFactor(textCmp.alignment);
for (int i = 0; i < linesVertexStartIndexes.Count; i++)
{
//行偏移(左中右)
float lineOffset = (linesVertexStartIndexes[i].Count - 1) * _textSpacing * alignmentFactor;
for (int j = 0; j < linesVertexStartIndexes[i].Count; j++)
{
int vertexStartIndex = linesVertexStartIndexes[i][j];
Vector3 offset = Vector3.right * ((_textSpacing * j) - lineOffset);
//对每个有效字体的六个顶点偏移
AddVertexOffset(vertexes, vertexStartIndex + 0, offset);
AddVertexOffset(vertexes, vertexStartIndex + 1, offset);
AddVertexOffset(vertexes, vertexStartIndex + 2, offset);
AddVertexOffset(vertexes, vertexStartIndex + 3, offset);
AddVertexOffset(vertexes, vertexStartIndex + 4, offset);
AddVertexOffset(vertexes, vertexStartIndex + 5, offset);
}
}
toFill.Clear();
toFill.AddUIVertexTriangleStream(vertexes);
}
//对顶点进行偏移
void AddVertexOffset(List<UIVertex> vertexes,int index,Vector3 offset)
{
UIVertex vertex = vertexes[index];
vertex.position += offset;
vertexes[index] = vertex;
}
//获取有效的初始顶点
List<List<int>> GetLinesVertexStartIndexes(Text textCmp)
{
List<List<int>> linesVertexIndexes = new List<List<int>>();
IList<UILineInfo> lineInfos = textCmp.cachedTextGenerator.lines;
for(int i=0;i<lineInfos.Count;i++)
{
List<int> lineVertexStartIndex = new List<int>();
int lineStart = lineInfos[i].startCharIdx;
int lineLength = (i < lineInfos.Count - 1) ? lineInfos[i + 1].startCharIdx - lineInfos[i].startCharIdx:textCmp.text.Length - lineInfos[i].startCharIdx;
//Rich Text根据正则表达式获取需要忽略的初始顶点
List<int> ignoreIndexes = new List<int>();
if (textCmp.supportRichText)
{
string line = textCmp.text.Substring(lineStart, lineLength);
foreach (Match matchTag in Regex.Matches(line, m_RichTextRegexPatterns))
{
for(int j=0;j<matchTag.Length;j++)
ignoreIndexes.Add(matchTag.Index + j);
}
}
for (int j = 0; j < lineLength; j++)
if (!ignoreIndexes.Contains(j))
lineVertexStartIndex.Add((lineStart+j)*6);
linesVertexIndexes.Add(lineVertexStartIndex);
}
return linesVertexIndexes;
}
//获取行偏移比例参数
float GetAlignmentFactor(TextAnchor alignment)
{
switch (alignment)
{
default:
Debug.LogError("Invalid Convertions Here!");
return 0;
case TextAnchor.UpperLeft:
case TextAnchor.MiddleLeft:
case TextAnchor.LowerLeft:
return 0;
case TextAnchor.UpperCenter:
case TextAnchor.MiddleCenter:
case TextAnchor.LowerCenter:
return .5f;
case TextAnchor.UpperRight:
case TextAnchor.MiddleRight:
case TextAnchor.LowerRight:
return 1f;
}
}
}