using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; using System.Collections.Generic; public class load_teammatesProfile : MonoBehaviour { private static Dictionary heroById; private static bool heroCacheReady; private static bool heroCacheBuilding; [Header("Inspector")] public Image teammate_profile_01; public Image teammate_profile_02; public Image teammate_profile_03; public Image teammate_profile_04; public Image teammate_profile_05; [Header("boarder")] public Image teammate_profile_boarder_01; public Image teammate_profile_boarder_02; public Image teammate_profile_boarder_03; public Image teammate_profile_boarder_04; public Image teammate_profile_boarder_05; [Header("Level Border Sprites")] public Sprite[] levelBorderSprites; [Header("Hover Details")] public loadDetailsPrefab hoverDetailsLoader; public GameObject hoverDetailsPrefab; public GameObject hoverDetailsParent; private bool hoverTargetsBound; private void Awake() { EnsureHoverTargetsBound(); } // Start is called once before the first execution of Update after the MonoBehaviour is created IEnumerator Start() { yield return EnsureHeroCache(); update_teammates_profile(); } private void EnsureHoverTargetsBound() { if (hoverTargetsBound) { return; } BindHoverTarget(teammate_profile_01, 1); BindHoverTarget(teammate_profile_02, 2); BindHoverTarget(teammate_profile_03, 3); BindHoverTarget(teammate_profile_04, 4); BindHoverTarget(teammate_profile_05, 5); hoverTargetsBound = true; } private void BindHoverTarget(Image targetImage, int slotIndex) { if (targetImage == null) { return; } TeammateProfileHoverTarget hoverTarget = targetImage.GetComponent(); if (hoverTarget == null) { hoverTarget = targetImage.gameObject.AddComponent(); } hoverTarget.Bind(this, slotIndex); } private IEnumerator EnsureHeroCache() { if (heroCacheReady) yield break; if (heroCacheBuilding) { while (!heroCacheReady) { yield return null; } yield break; } heroCacheBuilding = true; var allHeroes = RuntimeResourcesCache.LoadAllAllyHeroes(); heroById = new Dictionary(); if (allHeroes != null) { for (int i = 0; i < allHeroes.Length; i++) { var hero = allHeroes[i]; if (hero != null && !heroById.ContainsKey(hero.ally_heroID)) { heroById.Add(hero.ally_heroID, hero); } if ((i % 32) == 0) { yield return null; } } } heroCacheReady = true; heroCacheBuilding = false; } private IEnumerator EnsureHeroCacheThenUpdate() { yield return EnsureHeroCache(); update_teammates_profile(); } public void update_teammates_profile() { EnsureHoverTargetsBound(); if (!heroCacheReady) { StartCoroutine(EnsureHeroCacheThenUpdate()); return; } // Load selected hero IDs from PlayerPrefs int heroId1 = TeamSelectionDefaults.ReadHeroId(1); int heroId2 = TeamSelectionDefaults.ReadHeroId(2); int heroId3 = TeamSelectionDefaults.ReadHeroId(3); int heroId4 = TeamSelectionDefaults.ReadHeroId(4); int heroId5 = TeamSelectionDefaults.ReadHeroId(5); // Set sprites for each profile image teammate_profile_01.sprite = GetHeroSquareProfile(heroId1); teammate_profile_02.sprite = GetHeroSquareProfile(heroId2); teammate_profile_03.sprite = GetHeroSquareProfile(heroId3); teammate_profile_04.sprite = GetHeroSquareProfile(heroId4); teammate_profile_05.sprite = GetHeroSquareProfile(heroId5); // Set border sprites based on hero level ApplyBorderSprite(teammate_profile_boarder_01, GetHeroLevelKey(heroId1, 1)); ApplyBorderSprite(teammate_profile_boarder_02, GetHeroLevelKey(heroId2, 2)); ApplyBorderSprite(teammate_profile_boarder_03, GetHeroLevelKey(heroId3, 3)); ApplyBorderSprite(teammate_profile_boarder_04, GetHeroLevelKey(heroId4, 4)); ApplyBorderSprite(teammate_profile_boarder_05, GetHeroLevelKey(heroId5, 5)); } private Sprite GetHeroSquareProfile(int heroId) { if (heroId == 0 || heroById == null) return null; AllyHero_SO hero; if (heroById.TryGetValue(heroId, out hero) && hero != null) { return hero.ally_hero_squareProfile; } return null; } private string GetHeroLevelKey(int heroId, int slotIndex) { if (heroId == 0) return "Fallback"; if (heroById == null) return "Fallback"; AllyHero_SO hero; if (!heroById.TryGetValue(heroId, out hero) || hero == null) return "Fallback"; return GetRatingKeyFromSO(hero); } // 等级评级改从持久化账本(AllyHeroDeployLedger)取真值,而非 SO 上被打包烘焙的镜像字段, // 修复客户端更新后卡片显示过期等级、需重新给经验才同步的问题。 private string GetRatingKeyFromSO(AllyHero_SO so) { if (so == null || so.levelStats == null || so.levelStats.Count == 0) return "Fallback"; if (so.ally_heroID <= 0) { return so.GetDisplayLevelRatingKey(); } AllyHeroDeployLedger ledger = AllyHeroDeployLedger.EnsureInstance(); int currentExp = ledger.GetCurrentExp(so.ally_heroID); int unlockedTier = ledger.GetUnlockedTierIndex(so.ally_heroID); bool levelLocked = ledger.IsLevelLockEnabled(so.ally_heroID); return so.GetDisplayLevelRatingKeyFromGrowth(currentExp, unlockedTier, levelLocked); } private void ApplyBorderSprite(Image targetImage, string level) { if (targetImage == null) { return; } Sprite borderSprite = GetBorderSprite(level); targetImage.sprite = borderSprite; targetImage.color = Color.white; } private Sprite GetBorderSprite(string level) { if (levelBorderSprites == null || levelBorderSprites.Length == 0) { return null; } int index; switch (level) { case "Fallback": index = 4; break; case "C": index = 0; break; case "B": index = 1; break; case "A": index = 2; break; case "S": index = 3; break; default: index = 4; break; } if (index < 0 || index >= levelBorderSprites.Length) { return null; } return levelBorderSprites[index]; } public void ShowHeroDetailsForSlot(int slotIndex) { loadDetailsPrefab detailsLoader = ResolveDetailsLoader(); if (detailsLoader == null) { return; } if (!heroCacheReady) { return; } int heroId = GetSelectedHeroId(slotIndex); if (heroId == 0 || heroById == null) { return; } AllyHero_SO hero; if (!heroById.TryGetValue(heroId, out hero) || hero == null) { return; } string type = "\u89d2\u8272"; string name = string.IsNullOrEmpty(hero.ally_heroName) ? "\u672a\u77e5\u89d2\u8272" : hero.ally_heroName; string status = "\u53ef\u7528"; string description = string.IsNullOrEmpty(hero.ally_heroDescription) ? "\u65e0\u63cf\u8ff0" : hero.ally_heroDescription; if (hoverDetailsPrefab != null) { detailsLoader.detailsPrefab = hoverDetailsPrefab; } if (hoverDetailsParent != null) { detailsLoader.detailsParent = hoverDetailsParent; } detailsLoader.ShowDetails(type, name, status, description, Input.mousePosition); } public void HideHeroDetails() { loadDetailsPrefab detailsLoader = ResolveDetailsLoader(); if (detailsLoader != null) { detailsLoader.HideDetails(); } } private loadDetailsPrefab ResolveDetailsLoader() { if (hoverDetailsLoader != null) { return hoverDetailsLoader; } return loadDetailsPrefab.Instance; } private int GetSelectedHeroId(int slotIndex) { int keySlot = Mathf.Clamp(slotIndex, 1, 5); return PlayerPrefs.GetInt($"selected_heroSlot0{keySlot}_heroID", 0); } private sealed class TeammateProfileHoverTarget : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { private load_teammatesProfile owner; private int slotIndex; public void Bind(load_teammatesProfile targetOwner, int targetSlotIndex) { owner = targetOwner; slotIndex = targetSlotIndex; } public void OnPointerEnter(PointerEventData eventData) { if (owner != null) { owner.ShowHeroDetailsForSlot(slotIndex); } } public void OnPointerExit(PointerEventData eventData) { if (owner != null) { owner.HideHeroDetails(); } } } }