UGUI—文本字符串渐变

作者:追风剑情 发布于:2023-6-9 20:41 分类:Unity3d

一、工程截图

2222222.png

二、脚本

using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 字符渐变
/// </summary>
public class TextCharGradient : BaseMeshEffect
{
    [Tooltip("要渐变的字符索引号(从0开始)")]
    public int charIndex;
    [Tooltip("渐变偏移值")]
    [Range(0, 1)]
    public float gradientOffset;
    [Tooltip("渐变颜色")]
    public Color gradientColor = Color.blue;

    public override void ModifyMesh(VertexHelper vh)
    {
        if (!IsActive() || vh.currentVertCount == 0)
            return;

        //总顶点数
        int totalVertCount = vh.currentVertCount;
        //总字符数
        int totalCharCount = totalVertCount / 4;
        //最大字符索引
        int maxCharIndex = totalCharCount - 1;
        //规范参数取值范围
        charIndex = Mathf.Clamp(charIndex, 0, maxCharIndex);

        UIVertex vertex = new UIVertex();
        for (int i=0; i<=charIndex; i++)
        {
            int startVertexIndex = i * 4;
            if (i < charIndex)
            {
                //对当前字符之前的字符进行颜色固定
                //每个字符有4个顶点,顺序为: 左上、右上、右下、左下
                for (int j=0; j<4; j++)
                {
                    int vertexIndex = startVertexIndex + j;
                    vh.PopulateUIVertex(ref vertex, vertexIndex);
                    vertex.color = gradientColor;
                    vh.SetUIVertex(vertex, vertexIndex);
                }
                continue;
            }
            
            //对当前字符进行水平颜色渐变
            if (gradientOffset <= 0.5f)
            {
                //字符左边两个顶点颜色渐变
                float lt = gradientOffset * 2;
                vh.PopulateUIVertex(ref vertex, startVertexIndex);
                vertex.color = Color.Lerp(vertex.color, gradientColor, lt);
                vh.SetUIVertex(vertex, startVertexIndex);

                vh.PopulateUIVertex(ref vertex, startVertexIndex + 3);
                vertex.color = Color.Lerp(vertex.color, gradientColor, lt);
                vh.SetUIVertex(vertex, startVertexIndex + 3);
            }
            else
            {
                //字符左边两个顶点颜色固定
                float rt = (gradientOffset - 0.5f) * 2;
                vh.PopulateUIVertex(ref vertex, startVertexIndex);
                vertex.color = gradientColor;
                vh.SetUIVertex(vertex, startVertexIndex);

                vh.PopulateUIVertex(ref vertex, startVertexIndex + 3);
                vertex.color = gradientColor;
                vh.SetUIVertex(vertex, startVertexIndex + 3);

                //字符右边两个顶点颜色渐变
                vh.PopulateUIVertex(ref vertex, startVertexIndex + 1);
                vertex.color = Color.Lerp(vertex.color, gradientColor, rt);
                vh.SetUIVertex(vertex, startVertexIndex + 1);

                vh.PopulateUIVertex(ref vertex, startVertexIndex + 2);
                vertex.color = Color.Lerp(vertex.color, gradientColor, rt);
                vh.SetUIVertex(vertex, startVertexIndex + 2);
            }
        }
    }
}


using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 字符串渐变
/// </summary>
[RequireComponent(typeof(TextCharGradient))]
public class TextStringGradient : MonoBehaviour
{
    [Tooltip("播放速度")]
    public float speed = 5f;
    [Tooltip("暂停")]
    public bool pause = true;
    private Text m_Text;
    private TextCharGradient charGradient;
    private int charIndex;
    private float gradientOffset;

    private void Awake()
    {
        m_Text = this.GetComponent<Text>();
        charGradient = this.GetComponent<TextCharGradient>();
    }

    private void Update()
    {
        if (pause)
            return;

        if (charIndex >= m_Text.text.Length)
        {
            pause = true;
            return;
        }

        gradientOffset += speed * Time.deltaTime;
        charGradient.charIndex = charIndex;
        charGradient.gradientOffset = gradientOffset;

        if (gradientOffset >= 1)
        {
            charIndex++;
            gradientOffset = 0;
        }

        //顶点数据已脏,通知UGUI更新
        m_Text.SetVerticesDirty();
    }

    //播放
    public void Play()
    {
        pause = false;
        charIndex = 0;
        gradientOffset = 0;
    }
}


using UnityEngine;
using UnityEditor;
/// <summary>
/// Inspector UI
/// 此脚本放到 Assets/Editor/ 目录下
/// </summary>
[CustomEditor(typeof(TextStringGradient))]
[CanEditMultipleObjects]
public class TextStringGradientInspector : Editor
{
    protected TextStringGradient textStringGradient;

    protected virtual void OnEnable()
    {
        textStringGradient = target as TextStringGradient;
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();//保留Unity自动生成的Inspector
        if (GUILayout.Button("播放", GUILayout.Width(255)))
        {
            textStringGradient.Play();
        }
    }
}


将TextStringGradient.cs与Text组件挂在一起。点击Inspector上的“播放”按钮运行。
运行效果
11111.gif

标签: Unity3d

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号