基础
属性介绍
属性 | 说明 |
Text | 用于显示的文本 |
Font | 文本的字体 |
Font Style | 文本的样式(正常、加粗、斜线) |
Font Size | 字体的大小 |
Line Spacing | 文本行之间的间距 |
Rich Text | 是否支持富文本,富文本是带有标记标签的文本,增强文本的显示效果 |
Alignment | 文本的水平和垂直对齐方式 |
Align By Geometry | 是否以当前所显示的文字中获得的最大长宽(而不是字体的长宽)进行对齐 |
Horizontal Overflow | 文字横向溢出处理方式,可以选择Wrap隐藏或者Overflow溢出 |
Vertical Overflow | 文本纵向溢出的处理方式,可以选择Truncate截断或者Overflow溢出 |
Best Fit | 忽略Font Size设置的文字大小,自适应改变文字大小以适应文本框的大小 |
Color | 文本的颜色 |
Material | 用来渲染文本的材质,可以通过设置材质,让文本拥有更加炫酷的效果 |
Raycast Target | 是否可以被射线检测,通常情况下可以关闭,因为文本最好只用来显示 |
改变文字颜色
- 通过xxx颜色单词,调用Color中预设的颜色xxx进行设置
- 通过RGB进行设置
- 通过16进制颜色代码进行设置
- 通过
<color=xxx>content</color>
进行设置,xxx可以是以上三种形式,content
表示文字内容
using UnityEngine;
using UnityEngine.UI;
public class TextColorChange : MonoBehaviour
{
public Text text;
void Start()
{
// 1.
text.color = Color.white;
// 2.
text.color = new Color(129 / 255f, 69 / 255f, 69 / 255f, 255 / 255f);
// 3.
ColorUtility.TryParseHtmlString("#F2853E", out Color newColor);
text.color = newColor;
// 4.
text.text= "<color=red>你</color><color=rgb(255, 0, 0)>好</color><color=#0000ff>呀</color>";
}
}
设置字体
using UnityEngine;
using UnityEngine.UI;
public class TextColorChange : MonoBehaviour
{
public Text text;
public static string fontPath = "Assets/Fonts/";
public static string defaultFontName = "xxx";
public static string fontExt = ".ttf";
void Start()
{
var font = AssetDatabase.LoadAssetAtPath<Font>(fontPath + (string)defaultFontName + fontExt);
if (font)
{
text.font = font;
}
}
}
拓展
垂直文字
使用方式:
点击添加组件,将VerticalText脚本挂在物体上即可
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class VerticalText : Text
{
public bool IsVirtical = true;
private float lineSpace = 1;
private float textSpace = 1;
private float xOffset = 0;
private float yOffset = 0;
protected override void OnPopulateMesh(VertexHelper toFill)
{
base.OnPopulateMesh(toFill);
if (IsVirtical)
{
VirticalText(toFill);
}
}
private void VirticalText(VertexHelper toFill)
{
if (!IsActive())
return;
lineSpace = fontSize * lineSpacing;
textSpace = fontSize * lineSpacing;
xOffset = rectTransform.sizeDelta.x / 2 - fontSize / 2;
yOffset = rectTransform.sizeDelta.y / 2 - fontSize / 2;
for (int i = 0; i < cachedTextGenerator.lines.Count; i++)
{
UILineInfo line = cachedTextGenerator.lines[i];
int step = i;
if (i + 1 < cachedTextGenerator.lines.Count)
{
UILineInfo line2 = cachedTextGenerator.lines[i + 1];
int current = 0;
for (int j = line.startCharIdx; j < line2.startCharIdx - 1; j++)
{
modifyText(toFill, j, current++, step);
}
}
else if (i + 1 == cachedTextGenerator.lines.Count)
{
int current = 0;
for (int j = line.startCharIdx; j < cachedTextGenerator.characterCountVisible; j++)
{
modifyText(toFill, j, current++, step);
}
}
}
}
void modifyText(VertexHelper helper, int i, int charYPos, int charXPos)
{
UIVertex lb = new UIVertex();
helper.PopulateUIVertex(ref lb, i * 4);
UIVertex lt = new UIVertex();
helper.PopulateUIVertex(ref lt, i * 4 + 1);
UIVertex rt = new UIVertex();
helper.PopulateUIVertex(ref rt, i * 4 + 2);
UIVertex rb = new UIVertex();
helper.PopulateUIVertex(ref rb, i * 4 + 3);
Vector3 center = Vector3.Lerp(lb.position, rt.position, 0.5f);
Matrix4x4 move = Matrix4x4.TRS(-center, Quaternion.identity, Vector3.one);
float x = -charXPos * lineSpace + xOffset;
float y = -charYPos * textSpace + yOffset;
Vector3 pos = new Vector3(x, y, 0);
Matrix4x4 place = Matrix4x4.TRS(pos, Quaternion.identity, Vector3.one);
Matrix4x4 transform = place * move;
lb.position = transform.MultiplyPoint(lb.position);
lt.position = transform.MultiplyPoint(lt.position);
rt.position = transform.MultiplyPoint(rt.position);
rb.position = transform.MultiplyPoint(rb.position);
helper.SetUIVertex(lb, i * 4);
helper.SetUIVertex(lt, i * 4 + 1);
helper.SetUIVertex(rt, i * 4 + 2);
helper.SetUIVertex(rb, i * 4 + 3);
}
}
环形文字
原理:每个字符有四个顶点,分别为:左上,右上,右下,左下。只需修改字符顶点位置,即可使文字按圆形分布。
使用方式:
点击添加组件,将CircleText脚本挂在物体上,设置半径、间隔即可
using UnityEngine;
using UnityEngine.UI;
public class CircleText : BaseMeshEffect
{
public int radius = 100;
public float spaceCoff = 1f;
public override void ModifyMesh(VertexHelper vh)
{
if(!IsActive() || radius == 0)
{
return;
}
UIVertex lb = new UIVertex();
UIVertex lt = new UIVertex();
UIVertex rt = new UIVertex();
UIVertex rb = new UIVertex();
for(int i = 0; i < vh.currentVertCount / 4; i++)
{
vh.PopulateUIVertex(ref lb, i * 4);
vh.PopulateUIVertex(ref lt, i * 4 + 1);
vh.PopulateUIVertex(ref rt, i * 4 + 2);
vh.PopulateUIVertex(ref rb, i * 4 + 3);
Vector3 center = Vector3.Lerp(lb.position, rt.position, 0.5f);
Matrix4x4 move = Matrix4x4.TRS(center * -1, Quaternion.identity, Vector3.one);
float rad = Mathf.PI / 2 - center.x * spaceCoff / radius;
Vector3 pos = new Vector3(Mathf.Cos(rad), Mathf.Sin(rad), 0) * radius;
Quaternion rotation = Quaternion.Euler(0, 0, rad * 180 / Mathf.PI - 90);
Matrix4x4 rotate = Matrix4x4.TRS(Vector3.zero, rotation, Vector3.one);
Matrix4x4 place = Matrix4x4.TRS(pos, Quaternion.identity, Vector3.one);
Matrix4x4 transform = place * rotate * move;
lb.position = transform.MultiplyPoint(lb.position);
lt.position = transform.MultiplyPoint(lt.position);
rt.position = transform.MultiplyPoint(rt.position);
rb.position = transform.MultiplyPoint(rb.position);
lb.position.y = lb.position.y - radius + center.y;
lt.position.y = lt.position.y - radius + center.y;
rt.position.y = rt.position.y - radius + center.y;
rb.position.y = rb.position.y - radius + center.y;
vh.SetUIVertex(lb, i * 4);
vh.SetUIVertex(lt, i * 4 + 1);
vh.SetUIVertex(rt, i * 4 + 2);
vh.SetUIVertex(rb, i * 4 + 3);
}
}
}
字间距
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;
Text text;
protected override void Awake()
{
text = GetComponent<Text>();
}
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive() || vh.currentVertCount == 0)
{
return;
}
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);
}
}
}
}
}
参考资料
Unity UGUI Text竖排显示
UGUI圆形环绕文字实现
Unity3D-UGUI Text 文本调整字间距