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上的“播放”按钮运行。
运行效果