Files

201 lines
7.3 KiB
C#

using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class archievePrefab : MonoBehaviour
{
[Header("Inspector")]
public Image archieve_btmImage;
public TextMeshProUGUI archieve_name;
public TextMeshProUGUI archieve_description;
[Header("Rarity Background Sprites")]
public Sprite whiteLevelSprite;
public Sprite greenLevelSprite;
public Sprite blueLevelSprite;
public Sprite purpleLevelSprite;
public Sprite goldenLevelSprite;
public Sprite redLevelSprite;
public Sprite colorfulLevelSprite;
[Header("Name Text Colors")]
public Color whiteNameColor = Color.black;
public Color greenNameColor = Color.black;
public Color blueNameColor = Color.white;
public Color purpleNameColor = Color.white;
public Color goldenNameColor = Color.black;
public Color redNameColor = Color.white;
public Color colorfulNameColor = Color.black;
[Header("Description Gradient Colors")]
public bool overrideDescriptionToBlack = false;
public Gradient whiteDescGradient;
public bool whiteHorizontal;
public Gradient greenDescGradient;
public bool greenHorizontal;
public Gradient blueDescGradient;
public bool blueHorizontal;
public Gradient purpleDescGradient;
public bool purpleHorizontal;
public Gradient goldenDescGradient;
public bool goldenHorizontal;
public Gradient redDescGradient;
public bool redHorizontal;
public Gradient colorfulDescGradient;
public bool colorfulHorizontal;
public void Setup(AchievementLevel level)
{
if (archieve_name != null) archieve_name.text = level.levelName;
if (archieve_description != null) archieve_description.text = level.description;
SetRarityVisuals(level.rarity);
}
private void SetRarityVisuals(AchievementRarity rarity)
{
if (archieve_btmImage == null) return;
Sprite targetSprite = whiteLevelSprite;
Color targetNameColor = whiteNameColor;
Gradient targetGradient = whiteDescGradient;
bool isHorizontal = whiteHorizontal;
switch (rarity)
{
case AchievementRarity.Common:
targetSprite = whiteLevelSprite;
targetNameColor = whiteNameColor;
targetGradient = whiteDescGradient;
isHorizontal = whiteHorizontal;
break;
case AchievementRarity.Advanced:
targetSprite = greenLevelSprite;
targetNameColor = greenNameColor;
targetGradient = greenDescGradient;
isHorizontal = greenHorizontal;
break;
case AchievementRarity.Rare:
targetSprite = blueLevelSprite;
targetNameColor = blueNameColor;
targetGradient = blueDescGradient;
isHorizontal = blueHorizontal;
break;
case AchievementRarity.Epic:
targetSprite = purpleLevelSprite;
targetNameColor = purpleNameColor;
targetGradient = purpleDescGradient;
isHorizontal = purpleHorizontal;
break;
case AchievementRarity.Legendary:
targetSprite = goldenLevelSprite;
targetNameColor = goldenNameColor;
targetGradient = goldenDescGradient;
isHorizontal = goldenHorizontal;
break;
case AchievementRarity.Mythic:
targetSprite = redLevelSprite;
targetNameColor = redNameColor;
targetGradient = redDescGradient;
isHorizontal = redHorizontal;
break;
case AchievementRarity.Exquisite:
targetSprite = colorfulLevelSprite;
targetNameColor = colorfulNameColor;
targetGradient = colorfulDescGradient;
isHorizontal = colorfulHorizontal;
break;
}
// 1. 替换底图图片 (archieve_btmImage)
if (targetSprite != null)
{
archieve_btmImage.sprite = targetSprite;
archieve_btmImage.color = Color.white;
}
// 2. 设置成就名字颜色 (archieve_name)
if (archieve_name != null)
{
archieve_name.color = targetNameColor;
}
// 3. 设置描述文本渐变颜色 (archieve_description)
if (archieve_description != null && targetGradient != null)
{
ApplyGlobalGradient(archieve_description, targetGradient, isHorizontal);
}
}
/// <summary>
/// 将渐变色应用到整个文本对象,而不是单个字符
/// </summary>
private void ApplyGlobalGradient(TextMeshProUGUI textComponent, Gradient gradient, bool isHorizontal)
{
if (overrideDescriptionToBlack)
{
textComponent.color = Color.black;
textComponent.enableVertexGradient = false;
// 如果处于覆盖模式,直接返回,不执行复杂的顶点渐变逻辑
return;
}
// 必须先强制更新网格以获取正确的顶点数据
textComponent.ForceMeshUpdate();
TMP_TextInfo textInfo = textComponent.textInfo;
int characterCount = textInfo.characterCount;
if (characterCount == 0) return;
// 获取文本的边界(用于计算比例)
float minPos = isHorizontal ? textInfo.meshInfo[0].vertices[0].x : textInfo.meshInfo[0].vertices[0].y;
float maxPos = minPos;
for (int i = 0; i < characterCount; i++)
{
if (!textInfo.characterInfo[i].isVisible) continue;
int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
int vertexIndex = textInfo.characterInfo[i].vertexIndex;
Vector3[] vertices = textInfo.meshInfo[materialIndex].vertices;
for (int j = 0; j < 4; j++)
{
float pos = isHorizontal ? vertices[vertexIndex + j].x : vertices[vertexIndex + j].y;
if (pos < minPos) minPos = pos;
if (pos > maxPos) maxPos = pos;
}
}
float range = maxPos - minPos;
if (range < 0.001f) range = 1f;
// 再次遍历并应用颜色
for (int i = 0; i < characterCount; i++)
{
if (!textInfo.characterInfo[i].isVisible) continue;
int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
int vertexIndex = textInfo.characterInfo[i].vertexIndex;
Color32[] colors = textInfo.meshInfo[materialIndex].colors32;
Vector3[] vertices = textInfo.meshInfo[materialIndex].vertices;
for (int j = 0; j < 4; j++)
{
float pos = isHorizontal ? vertices[vertexIndex + j].x : vertices[vertexIndex + j].y;
// 计算该顶点在整个范围内的 normalized 位置 (0-1)
float t = (pos - minPos) / range;
// 如果是垂直渐变,通常是从上到下,而 Y 轴向上,所以需要反转 t
if (!isHorizontal) t = 1f - t;
colors[vertexIndex + j] = gradient.Evaluate(t);
}
}
// 更新网格颜色
textComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
}