using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
///
/// 支持渐变效果的文本组件
///
public class GradientText : Text
{
[Header("渐变设置")]
[SerializeField]
private GradientType m_GradientType = GradientType.Horizontal;
[SerializeField]
private Color m_TopLeftColor = Color.white;
[SerializeField]
private Color m_TopRightColor = Color.white;
[SerializeField]
private Color m_BottomLeftColor = Color.white;
[SerializeField]
private Color m_BottomRightColor = Color.white;
[SerializeField]
private bool m_UseGradient = true;
public enum GradientType
{
Horizontal, // 水平渐变
Vertical, // 垂直渐变
Diagonal, // 对角线渐变
Radial, // 径向渐变
Custom // 自定义四角颜色
}
public GradientType gradientType
{
get { return m_GradientType; }
set
{
if (m_GradientType != value)
{
m_GradientType = value;
SetVerticesDirty();
}
}
}
public Color topLeftColor
{
get { return m_TopLeftColor; }
set
{
if (m_TopLeftColor != value)
{
m_TopLeftColor = value;
SetVerticesDirty();
}
}
}
public Color topRightColor
{
get { return m_TopRightColor; }
set
{
if (m_TopRightColor != value)
{
m_TopRightColor = value;
SetVerticesDirty();
}
}
}
public Color bottomLeftColor
{
get { return m_BottomLeftColor; }
set
{
if (m_BottomLeftColor != value)
{
m_BottomLeftColor = value;
SetVerticesDirty();
}
}
}
public Color bottomRightColor
{
get { return m_BottomRightColor; }
set
{
if (m_BottomRightColor != value)
{
m_BottomRightColor = value;
SetVerticesDirty();
}
}
}
public bool useGradient
{
get { return m_UseGradient; }
set
{
if (m_UseGradient != value)
{
m_UseGradient = value;
SetVerticesDirty();
}
}
}
///
/// 设置水平渐变颜色
///
public void SetHorizontalGradient(Color leftColor, Color rightColor)
{
m_GradientType = GradientType.Horizontal;
m_TopLeftColor = leftColor;
m_BottomLeftColor = leftColor;
m_TopRightColor = rightColor;
m_BottomRightColor = rightColor;
SetVerticesDirty();
}
///
/// 设置垂直渐变颜色
///
public void SetVerticalGradient(Color topColor, Color bottomColor)
{
m_GradientType = GradientType.Vertical;
m_TopLeftColor = topColor;
m_TopRightColor = topColor;
m_BottomLeftColor = bottomColor;
m_BottomRightColor = bottomColor;
SetVerticesDirty();
}
///
/// 设置对角线渐变颜色
///
public void SetDiagonalGradient(Color topLeftColor, Color bottomRightColor)
{
m_GradientType = GradientType.Diagonal;
m_TopLeftColor = topLeftColor;
m_BottomRightColor = bottomRightColor;
// 计算中间颜色
m_TopRightColor = Color.Lerp(topLeftColor, bottomRightColor, 0.5f);
m_BottomLeftColor = Color.Lerp(topLeftColor, bottomRightColor, 0.5f);
SetVerticesDirty();
}
///
/// 设置径向渐变颜色
///
public void SetRadialGradient(Color centerColor, Color edgeColor)
{
m_GradientType = GradientType.Radial;
m_TopLeftColor = edgeColor;
m_TopRightColor = edgeColor;
m_BottomLeftColor = edgeColor;
m_BottomRightColor = edgeColor;
// 径向渐变需要在顶点着色器中处理
SetVerticesDirty();
}
protected override void OnPopulateMesh(VertexHelper vh)
{
base.OnPopulateMesh(vh);
if (!m_UseGradient)
return;
if (!IsActive())
return;
// 获取顶点数据
var vertexCount = vh.currentVertCount;
if (vertexCount == 0)
return;
// 计算文本的边界框
var vertices = new List();
vh.GetUIVertexStream(vertices);
var bounds = new Bounds(vertices[0].position, Vector3.zero);
for (int i = 1; i < vertices.Count; i++)
{
bounds.Encapsulate(vertices[i].position);
}
// 应用渐变颜色
for (int i = 0; i < vertices.Count; i++)
{
var vertex = vertices[i];
var pos = vertex.position;
// 计算相对于边界框的归一化坐标
var normalizedX = (pos.x - bounds.min.x) / bounds.size.x;
var normalizedY = (pos.y - bounds.min.y) / bounds.size.y;
Color color = CalculateGradientColor(normalizedX, normalizedY);
vertex.color = color;
vertices[i] = vertex;
}
vh.Clear();
vh.AddUIVertexTriangleStream(vertices);
}
private Color CalculateGradientColor(float x, float y)
{
switch (m_GradientType)
{
case GradientType.Horizontal:
return Color.Lerp(m_TopLeftColor, m_TopRightColor, x);
case GradientType.Vertical:
return Color.Lerp(m_TopLeftColor, m_BottomLeftColor, y);
case GradientType.Diagonal:
return Color.Lerp(m_TopLeftColor, m_BottomRightColor, (x + y) * 0.5f);
case GradientType.Radial:
var center = new Vector2(0.5f, 0.5f);
var distance = Vector2.Distance(new Vector2(x, y), center);
return Color.Lerp(m_TopLeftColor, m_BottomRightColor, distance * 2f);
case GradientType.Custom:
// 双线性插值
var topColor = Color.Lerp(m_TopLeftColor, m_TopRightColor, x);
var bottomColor = Color.Lerp(m_BottomLeftColor, m_BottomRightColor, x);
return Color.Lerp(topColor, bottomColor, y);
default:
return color;
}
}
protected override void Awake()
{
base.Awake();
// 设置默认颜色
if (m_TopLeftColor == Color.white && m_TopRightColor == Color.white &&
m_BottomLeftColor == Color.white && m_BottomRightColor == Color.white)
{
// 设置默认的渐变颜色
m_TopLeftColor = Color.red;
m_TopRightColor = Color.blue;
m_BottomLeftColor = Color.green;
m_BottomRightColor = Color.yellow;
}
}
}