Files
Ultimate-Fishing-Simulator-…/Assets/Scripts/Assembly-CSharp/Michsky/UI/MTP/UIGradient.cs
2026-03-04 09:37:33 +08:00

498 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Michsky.UI.MTP
{
[AddComponentMenu("Modern UI Pack/Effects/UI Gradient")]
public class UIGradient : BaseMeshEffect
{
public enum Type
{
Horizontal = 0,
Vertical = 1,
Diamond = 2
}
public enum Blend
{
Override = 0,
Add = 1,
Multiply = 2
}
[SerializeField]
private Type _gradientType;
[SerializeField]
private Blend _blendMode = Blend.Multiply;
[SerializeField]
private bool _modifyVertices = true;
[SerializeField]
[Range(-1f, 1f)]
private float _offset;
[SerializeField]
[Range(0.1f, 10f)]
private float _zoom = 1f;
[SerializeField]
private Gradient _effectGradient = new Gradient
{
colorKeys = new GradientColorKey[2]
{
new GradientColorKey(Color.black, 0f),
new GradientColorKey(Color.white, 1f)
}
};
public Blend BlendMode
{
get
{
return _blendMode;
}
set
{
_blendMode = value;
base.graphic.SetVerticesDirty();
}
}
public Gradient EffectGradient
{
get
{
return _effectGradient;
}
set
{
_effectGradient = value;
base.graphic.SetVerticesDirty();
}
}
public Type GradientType
{
get
{
return _gradientType;
}
set
{
_gradientType = value;
base.graphic.SetVerticesDirty();
}
}
public bool ModifyVertices
{
get
{
return _modifyVertices;
}
set
{
_modifyVertices = value;
base.graphic.SetVerticesDirty();
}
}
public float Offset
{
get
{
return _offset;
}
set
{
_offset = Mathf.Clamp(value, -1f, 1f);
base.graphic.SetVerticesDirty();
}
}
public float Zoom
{
get
{
return _zoom;
}
set
{
_zoom = Mathf.Clamp(value, 0.1f, 10f);
base.graphic.SetVerticesDirty();
}
}
public override void ModifyMesh(VertexHelper helper)
{
if (!IsActive() || helper.currentVertCount == 0)
{
return;
}
List<UIVertex> list = new List<UIVertex>();
helper.GetUIVertexStream(list);
int count = list.Count;
switch (GradientType)
{
case Type.Horizontal:
case Type.Vertical:
{
Rect bounds2 = GetBounds(list);
float num3 = bounds2.xMin;
float num4 = bounds2.width;
Func<UIVertex, float> func = (UIVertex v) => v.position.x;
if (GradientType == Type.Vertical)
{
num3 = bounds2.yMin;
num4 = bounds2.height;
func = (UIVertex v) => v.position.y;
}
float num5 = ((num4 == 0f) ? 0f : (1f / num4 / Zoom));
float num6 = (1f - 1f / Zoom) * 0.5f;
float num7 = Offset * (1f - num6) - num6;
if (ModifyVertices)
{
SplitTrianglesAtGradientStops(list, bounds2, num6, helper);
}
UIVertex vertex2 = default(UIVertex);
for (int num8 = 0; num8 < helper.currentVertCount; num8++)
{
helper.PopulateUIVertex(ref vertex2, num8);
vertex2.color = BlendColor(vertex2.color, EffectGradient.Evaluate((func(vertex2) - num3) * num5 - num7));
helper.SetUIVertex(vertex2, num8);
}
break;
}
case Type.Diamond:
{
Rect bounds = GetBounds(list);
float num = ((bounds.height == 0f) ? 0f : (1f / bounds.height / Zoom));
float num2 = bounds.center.y / 2f;
Vector3 vector = (Vector3.right + Vector3.up) * num2 + Vector3.forward * list[0].position.z;
if (ModifyVertices)
{
helper.Clear();
for (int i = 0; i < count; i++)
{
helper.AddVert(list[i]);
}
helper.AddVert(new UIVertex
{
position = vector,
normal = list[0].normal,
uv0 = new Vector2(0.5f, 0.5f),
color = Color.white
});
for (int j = 1; j < count; j++)
{
helper.AddTriangle(j - 1, j, count);
}
helper.AddTriangle(0, count - 1, count);
}
UIVertex vertex = default(UIVertex);
for (int k = 0; k < helper.currentVertCount; k++)
{
helper.PopulateUIVertex(ref vertex, k);
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(Vector3.Distance(vertex.position, vector) * num - Offset));
helper.SetUIVertex(vertex, k);
}
break;
}
}
}
private Rect GetBounds(List<UIVertex> vertices)
{
float num = vertices[0].position.x;
float num2 = num;
float num3 = vertices[0].position.y;
float num4 = num3;
for (int num5 = vertices.Count - 1; num5 >= 1; num5--)
{
float x = vertices[num5].position.x;
float y = vertices[num5].position.y;
if (x > num2)
{
num2 = x;
}
else if (x < num)
{
num = x;
}
if (y > num4)
{
num4 = y;
}
else if (y < num3)
{
num3 = y;
}
}
return new Rect(num, num3, num2 - num, num4 - num3);
}
private void SplitTrianglesAtGradientStops(List<UIVertex> _vertexList, Rect bounds, float zoomOffset, VertexHelper helper)
{
List<float> list = FindStops(zoomOffset, bounds);
if (list.Count <= 0)
{
return;
}
helper.Clear();
int count = _vertexList.Count;
for (int i = 0; i < count; i += 3)
{
float[] positions = GetPositions(_vertexList, i);
List<int> list2 = new List<int>(3);
List<UIVertex> list3 = new List<UIVertex>(3);
List<UIVertex> list4 = new List<UIVertex>(2);
for (int j = 0; j < list.Count; j++)
{
int currentVertCount = helper.currentVertCount;
bool flag = list4.Count > 0;
bool flag2 = false;
for (int k = 0; k < 3; k++)
{
if (!list2.Contains(k) && positions[k] < list[j])
{
int num = (k + 1) % 3;
UIVertex item = _vertexList[k + i];
if (positions[num] > list[j])
{
list2.Insert(0, k);
list3.Insert(0, item);
flag2 = true;
}
else
{
list2.Add(k);
list3.Add(item);
}
}
}
if (list2.Count == 0)
{
continue;
}
if (list2.Count == 3)
{
break;
}
foreach (UIVertex item3 in list3)
{
helper.AddVert(item3);
}
list4.Clear();
foreach (int item4 in list2)
{
int num2 = (item4 + 1) % 3;
if (positions[num2] < list[j])
{
num2 = (num2 + 1) % 3;
}
list4.Add(CreateSplitVertex(_vertexList[item4 + i], _vertexList[num2 + i], list[j]));
}
if (list4.Count == 1)
{
int num3 = (list2[0] + 2) % 3;
list4.Add(CreateSplitVertex(_vertexList[list2[0] + i], _vertexList[num3 + i], list[j]));
}
foreach (UIVertex item5 in list4)
{
helper.AddVert(item5);
}
if (flag)
{
helper.AddTriangle(currentVertCount - 2, currentVertCount, currentVertCount + 1);
helper.AddTriangle(currentVertCount - 2, currentVertCount + 1, currentVertCount - 1);
if (list3.Count > 0)
{
if (flag2)
{
helper.AddTriangle(currentVertCount - 2, currentVertCount + 3, currentVertCount);
}
else
{
helper.AddTriangle(currentVertCount + 1, currentVertCount + 3, currentVertCount - 1);
}
}
}
else
{
int currentVertCount2 = helper.currentVertCount;
helper.AddTriangle(currentVertCount, currentVertCount2 - 2, currentVertCount2 - 1);
if (list3.Count > 1)
{
helper.AddTriangle(currentVertCount, currentVertCount2 - 1, currentVertCount + 1);
}
}
list3.Clear();
}
if (list4.Count > 0)
{
if (list3.Count == 0)
{
for (int l = 0; l < 3; l++)
{
if (!list2.Contains(l) && positions[l] > list[list.Count - 1])
{
int num4 = (l + 1) % 3;
UIVertex item2 = _vertexList[l + i];
if (positions[num4] > list[list.Count - 1])
{
list3.Insert(0, item2);
}
else
{
list3.Add(item2);
}
}
}
}
foreach (UIVertex item6 in list3)
{
helper.AddVert(item6);
}
int currentVertCount3 = helper.currentVertCount;
if (list3.Count > 1)
{
helper.AddTriangle(currentVertCount3 - 4, currentVertCount3 - 2, currentVertCount3 - 1);
helper.AddTriangle(currentVertCount3 - 4, currentVertCount3 - 1, currentVertCount3 - 3);
}
else if (list3.Count > 0)
{
helper.AddTriangle(currentVertCount3 - 3, currentVertCount3 - 1, currentVertCount3 - 2);
}
}
else
{
helper.AddVert(_vertexList[i]);
helper.AddVert(_vertexList[i + 1]);
helper.AddVert(_vertexList[i + 2]);
int currentVertCount4 = helper.currentVertCount;
helper.AddTriangle(currentVertCount4 - 3, currentVertCount4 - 2, currentVertCount4 - 1);
}
}
}
private float[] GetPositions(List<UIVertex> _vertexList, int index)
{
float[] array = new float[3];
if (GradientType == Type.Horizontal)
{
array[0] = _vertexList[index].position.x;
array[1] = _vertexList[index + 1].position.x;
array[2] = _vertexList[index + 2].position.x;
}
else
{
array[0] = _vertexList[index].position.y;
array[1] = _vertexList[index + 1].position.y;
array[2] = _vertexList[index + 2].position.y;
}
return array;
}
private List<float> FindStops(float zoomOffset, Rect bounds)
{
List<float> list = new List<float>();
float num = Offset * (1f - zoomOffset);
float num2 = zoomOffset - num;
float num3 = 1f - zoomOffset - num;
GradientColorKey[] colorKeys = EffectGradient.colorKeys;
for (int i = 0; i < colorKeys.Length; i++)
{
GradientColorKey gradientColorKey = colorKeys[i];
if (gradientColorKey.time >= num3)
{
break;
}
if (gradientColorKey.time > num2)
{
list.Add((gradientColorKey.time - num2) * Zoom);
}
}
GradientAlphaKey[] alphaKeys = EffectGradient.alphaKeys;
for (int i = 0; i < alphaKeys.Length; i++)
{
GradientAlphaKey gradientAlphaKey = alphaKeys[i];
if (gradientAlphaKey.time >= num3)
{
break;
}
if (gradientAlphaKey.time > num2)
{
list.Add((gradientAlphaKey.time - num2) * Zoom);
}
}
float num4 = bounds.xMin;
float num5 = bounds.width;
if (GradientType == Type.Vertical)
{
num4 = bounds.yMin;
num5 = bounds.height;
}
list.Sort();
for (int j = 0; j < list.Count; j++)
{
list[j] = list[j] * num5 + num4;
if (j > 0 && Math.Abs(list[j] - list[j - 1]) < 2f)
{
list.RemoveAt(j);
j--;
}
}
return list;
}
private UIVertex CreateSplitVertex(UIVertex vertex1, UIVertex vertex2, float stop)
{
if (GradientType == Type.Horizontal)
{
float num = vertex1.position.x - stop;
float num2 = vertex1.position.x - vertex2.position.x;
float num3 = vertex1.position.y - vertex2.position.y;
float num4 = vertex1.uv0.x - vertex2.uv0.x;
float num5 = vertex1.uv0.y - vertex2.uv0.y;
float num6 = num / num2;
float y = vertex1.position.y - num3 * num6;
return new UIVertex
{
position = new Vector3(stop, y, vertex1.position.z),
normal = vertex1.normal,
uv0 = new Vector2(vertex1.uv0.x - num4 * num6, vertex1.uv0.y - num5 * num6),
color = Color.white
};
}
float num7 = vertex1.position.y - stop;
float num8 = vertex1.position.y - vertex2.position.y;
float num9 = vertex1.position.x - vertex2.position.x;
float num10 = vertex1.uv0.x - vertex2.uv0.x;
float num11 = vertex1.uv0.y - vertex2.uv0.y;
float num12 = num7 / num8;
float x = vertex1.position.x - num9 * num12;
return new UIVertex
{
position = new Vector3(x, stop, vertex1.position.z),
normal = vertex1.normal,
uv0 = new Vector2(vertex1.uv0.x - num10 * num12, vertex1.uv0.y - num11 * num12),
color = Color.white
};
}
private Color BlendColor(Color colorA, Color colorB)
{
return BlendMode switch
{
Blend.Add => colorA + colorB,
Blend.Multiply => colorA * colorB,
_ => colorB,
};
}
}
}