Files
bansonic_beta_main/Assets/idolsDisplay/UI_Idols.cs
T

323 lines
8.7 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using System.Runtime.ExceptionServices;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class UI_Idols : MonoBehaviour
{
[Header("prefabs")]
public GameObject idolCardPrefab;
public Transform idolCardParent;
[Header("sprites")]
public Sprite[] idolLevelIcons;
public Sprite[] idolBtm;
[Header("colors")]
public Color[] idolSliderColors;
[Header("paths")]
public string idolSOpath_runtime;
public string idolSOpath_editor;
[Header("scan")]
public bool includeLockedHeroes = false;
[Header("rightPanel")]
public GameObject righePanel;
private readonly List<GameObject> spawnedCards = new List<GameObject>();
private void Start()
{
RebuildCards();
}
private void OnEnable()
{
RebuildCards();
}
[ContextMenu("Rebuild Idols")]
public void RebuildCards()
{
if (idolCardPrefab == null || idolCardParent == null)
{
return;
}
ClearCards();
List<AllyHero_SO> heroes = LoadHeroAssets();
if (heroes.Count == 0)
{
return;
}
heroes.Sort((left, right) => left.ally_heroID.CompareTo(right.ally_heroID));
for (int i = 0; i < heroes.Count; i++)
{
AllyHero_SO hero = heroes[i];
if (hero == null)
{
continue;
}
if (!includeLockedHeroes && !hero.isUnlocked)
{
continue;
}
IdolLevelSnapshot snapshot = BuildLevelSnapshot(hero);
GameObject instance = Instantiate(idolCardPrefab, idolCardParent);
spawnedCards.Add(instance);
idolCardPrefab card = instance.GetComponent<idolCardPrefab>();
if (card == null)
{
continue;
}
card.Setup(
hero.ally_hero_squareProfile,
hero.ally_heroDesignation,
hero.ally_heroName,
snapshot.sliderValue,
snapshot.xpText,
snapshot.levelIcon,
snapshot.bottomSprite,
snapshot.sliderColor);
}
}
private List<AllyHero_SO> LoadHeroAssets()
{
List<AllyHero_SO> heroes = new List<AllyHero_SO>();
#if UNITY_EDITOR
if (!Application.isPlaying && !string.IsNullOrWhiteSpace(idolSOpath_editor))
{
string[] searchFolders = { idolSOpath_editor };
string[] guids = AssetDatabase.FindAssets("t:AllyHero_SO", searchFolders);
for (int i = 0; i < guids.Length; i++)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
AllyHero_SO hero = AssetDatabase.LoadAssetAtPath<AllyHero_SO>(assetPath);
if (hero != null)
{
heroes.Add(hero);
}
}
return heroes;
}
#endif
AllyHero_SO[] loadedHeroes = Resources.LoadAll<AllyHero_SO>(string.IsNullOrWhiteSpace(idolSOpath_runtime) ? string.Empty : idolSOpath_runtime);
for (int i = 0; i < loadedHeroes.Length; i++)
{
if (loadedHeroes[i] != null)
{
heroes.Add(loadedHeroes[i]);
}
}
return heroes;
}
private IdolLevelSnapshot BuildLevelSnapshot(AllyHero_SO hero)
{
IdolLevelSnapshot snapshot = new IdolLevelSnapshot
{
sliderValue = 0f,
xpText = "UNKNOWN",
levelIcon = GetLevelIconByIndex(4),
bottomSprite = GetBottomSpriteByIndex(4),
sliderColor = GetSliderColorByIndex(4)
};
if (hero == null)
{
return snapshot;
}
List<AllyHero_SO.AllyLevelInfo> levels = new List<AllyHero_SO.AllyLevelInfo>();
if (hero.levelStats != null)
{
for (int i = 0; i < hero.levelStats.Count; i++)
{
if (hero.levelStats[i] != null)
{
levels.Add(hero.levelStats[i]);
}
}
}
if (levels.Count == 0)
{
return snapshot;
}
levels.Sort((left, right) => left.requiredEXP.CompareTo(right.requiredEXP));
int currentExp = Mathf.Max(0, hero.ally_currentEXP);
int currentLevelIndex = -1;
for (int i = 0; i < levels.Count; i++)
{
if (currentExp >= levels[i].requiredEXP)
{
currentLevelIndex = i;
}
}
int displayIndex = Mathf.Clamp(currentLevelIndex >= 0 ? currentLevelIndex : 0, 0, levels.Count - 1);
AllyHero_SO.AllyLevelInfo currentLevel = levels[displayIndex];
int tierIndex = ResolveTierIndex(currentLevel, displayIndex, levels.Count);
snapshot.levelIcon = GetLevelIconByIndex(tierIndex);
snapshot.bottomSprite = GetBottomSpriteByIndex(tierIndex);
snapshot.sliderColor = GetSliderColorByIndex(tierIndex);
if (displayIndex >= levels.Count - 1 && currentExp >= currentLevel.requiredEXP)
{
snapshot.sliderValue = 1f;
snapshot.xpText = "MAX";
return snapshot;
}
int floorExp = currentLevelIndex >= 0 ? currentLevel.requiredEXP : 0;
int nextLevelIndex = Mathf.Clamp(displayIndex + 1, 0, levels.Count - 1);
int nextExp = levels[nextLevelIndex].requiredEXP;
int range = Mathf.Max(1, nextExp - floorExp);
int gained = Mathf.Clamp(currentExp - floorExp, 0, range);
snapshot.sliderValue = Mathf.Clamp01(gained / (float)range);
int neededExp = nextExp - currentExp;
if (neededExp > 0)
{
snapshot.xpText = "NEED " + neededExp + " EXP";
}
else if (displayIndex >= levels.Count - 1)
{
snapshot.xpText = "MAX";
}
return snapshot;
}
private int ResolveTierIndex(AllyHero_SO.AllyLevelInfo levelInfo, int levelIndex, int levelCount)
{
if (levelInfo != null && !string.IsNullOrWhiteSpace(levelInfo.levelName))
{
string normalized = levelInfo.levelName.Trim().ToUpperInvariant();
if (normalized.Contains("S")) return 3;
if (normalized.Contains("A")) return 2;
if (normalized.Contains("B")) return 1;
if (normalized.Contains("C")) return 0;
}
if (levelCount <= 1)
{
return 0;
}
float normalizedIndex = levelIndex / (float)Mathf.Max(1, levelCount - 1);
if (normalizedIndex >= 0.99f) return 3;
if (normalizedIndex >= 0.66f) return 2;
if (normalizedIndex >= 0.33f) return 1;
return 0;
}
private Sprite GetLevelIconByIndex(int index)
{
if (idolLevelIcons == null || idolLevelIcons.Length == 0)
{
return null;
}
return idolLevelIcons[Mathf.Clamp(index, 0, idolLevelIcons.Length - 1)];
}
private Sprite GetBottomSpriteByIndex(int index)
{
if (idolBtm == null || idolBtm.Length == 0)
{
return null;
}
return idolBtm[Mathf.Clamp(index, 0, idolBtm.Length - 1)];
}
private Color GetSliderColorByIndex(int index)
{
if (idolSliderColors == null || idolSliderColors.Length == 0)
{
return Color.white;
}
return idolSliderColors[Mathf.Clamp(index, 0, idolSliderColors.Length - 1)];
}
private void ClearCards()
{
for (int i = spawnedCards.Count - 1; i >= 0; i--)
{
if (spawnedCards[i] == null)
{
continue;
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
DestroyImmediate(spawnedCards[i]);
}
else
#endif
{
Destroy(spawnedCards[i]);
}
}
spawnedCards.Clear();
if (idolCardParent == null)
{
return;
}
for (int i = idolCardParent.childCount - 1; i >= 0; i--)
{
Transform child = idolCardParent.GetChild(i);
if (child == null || child.GetComponent<idolCardPrefab>() == null)
{
continue;
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
DestroyImmediate(child.gameObject);
}
else
#endif
{
Destroy(child.gameObject);
}
}
}
private struct IdolLevelSnapshot
{
public float sliderValue;
public string xpText;
public Sprite levelIcon;
public Sprite bottomSprite;
public Color sliderColor;
}
}