基础

属性介绍

属性

说明

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

是否可以被射线检测,通常情况下可以关闭,因为文本最好只用来显示

改变文字颜色

  1. 通过xxx颜色单词,调用Color中预设的颜色xxx进行设置
  2. 通过RGB进行设置
  3. 通过16进制颜色代码进行设置
  4. 通过<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 文本调整字间距