using UnityEngine;
|
using UnityEngine.UI;
|
using System.Collections.Generic;
|
|
/// <summary>
|
/// 支持渐变效果的文本组件
|
/// </summary>
|
public class GradientText : RichText
|
{
|
[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();
|
}
|
}
|
}
|
|
/// <summary>
|
/// 设置水平渐变颜色
|
/// </summary>
|
public void SetHorizontalGradient(Color leftColor, Color rightColor)
|
{
|
m_GradientType = GradientType.Horizontal;
|
m_TopLeftColor = leftColor;
|
m_BottomLeftColor = leftColor;
|
m_TopRightColor = rightColor;
|
m_BottomRightColor = rightColor;
|
SetVerticesDirty();
|
}
|
|
/// <summary>
|
/// 设置垂直渐变颜色
|
/// </summary>
|
public void SetVerticalGradient(Color topColor, Color bottomColor)
|
{
|
m_GradientType = GradientType.Vertical;
|
m_TopLeftColor = topColor;
|
m_TopRightColor = topColor;
|
m_BottomLeftColor = bottomColor;
|
m_BottomRightColor = bottomColor;
|
SetVerticesDirty();
|
}
|
|
/// <summary>
|
/// 设置对角线渐变颜色
|
/// </summary>
|
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();
|
}
|
|
/// <summary>
|
/// 设置径向渐变颜色
|
/// </summary>
|
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<UIVertex>();
|
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;
|
}
|
}
|
}
|