hch
10 小时以前 1853d0c29d1ab65f9a06345a5f92eeb6c355921c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
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;
        }
    }
}