using System.Collections; using System.Collections.Generic; using System.Globalization; using TMPro; using UnityEngine; using UnityEngine.UI; using UObject = UnityEngine.Object; namespace XGame { public sealed class PlayerProfileModule : MonoBehaviour { private const string HudPrefabPath = "Assets/Game/Art/UI/Prefab/UI_PlayerProfileHud.prefab"; private const string PanelPrefabPath = "Assets/Game/Art/UI/Prefab/UI_PlayerProfilePanel.prefab"; private const string AvatarPickerPrefabPath = "Assets/Game/Art/UI/Prefab/UI_PlayerAvatarPicker.prefab"; private const float PreviewAvatarFrameFill = 0.58f; private GameObject hudView; private GameObject detailView; private GameObject avatarPickerView; private bool openingHud; private bool openingDetail; private bool openingAvatarPicker; private int openVersion; private int avatarPickerVersion; private int pendingAvatarId; private TMP_Text hudNicknameText; private TMP_Text hudLevelText; private TMP_Text hudExpText; private Image hudAvatarImage; private Image detailAvatarImage; private RectTransform hudExpFill; private RectTransform hudExpTrack; private Image avatarPickerPreviewImage; private TMP_Text avatarPickerHintText; private readonly Dictionary avatarSpriteCache = new Dictionary(); private readonly HashSet loadingAvatarIds = new HashSet(); private readonly Dictionary avatarPickerAvatarImages = new Dictionary(); private readonly Dictionary avatarPickerSelectedStates = new Dictionary(); private void OnEnable() { PlayerProfileStore.Changed += OnProfileChanged; } private void OnDisable() { PlayerProfileStore.Changed -= OnProfileChanged; } public bool IsOpen => hudView != null; public IEnumerator OpenAsync() { if (hudView != null || openingHud) { RefreshAll(PlayerProfileStore.Current); yield break; } openingHud = true; int version = ++openVersion; UObject loaded = null; yield return XResLoader.coLoadRes(HudPrefabPath, typeof(GameObject), obj => loaded = obj); openingHud = false; if (version != openVersion) { yield break; } GameObject prefab = loaded as GameObject; if (prefab == null) { Debug.LogError("[PlayerProfileModule] load HUD prefab failed: " + HudPrefabPath); yield break; } hudView = Instantiate(prefab); UIManager.AttachTo(UILayer.HUD, hudView); CacheHudControls(); BindHudEvents(); RefreshHud(PlayerProfileStore.Current); } public void Close() { openVersion++; openingHud = false; openingDetail = false; openingAvatarPicker = false; avatarPickerVersion++; if (hudView != null) { Destroy(hudView); } if (detailView != null) { Destroy(detailView); } if (avatarPickerView != null) { Destroy(avatarPickerView); } hudView = null; detailView = null; hudNicknameText = null; hudLevelText = null; hudExpText = null; hudExpFill = null; hudExpTrack = null; hudAvatarImage = null; detailAvatarImage = null; avatarPickerView = null; avatarPickerPreviewImage = null; avatarPickerHintText = null; pendingAvatarId = 0; avatarPickerAvatarImages.Clear(); avatarPickerSelectedStates.Clear(); loadingAvatarIds.Clear(); avatarSpriteCache.Clear(); } private void OnProfileChanged(PlayerProfileData profile) { RefreshAll(profile); } private void RefreshAll(PlayerProfileData profile) { RefreshHud(profile); RefreshDetail(profile); } private void CacheHudControls() { if (hudView == null) { return; } hudNicknameText = FindComponent(hudView, "Txt_Nickname"); hudLevelText = FindComponent(hudView, "Txt_Level"); hudExpText = FindComponent(hudView, "Txt_Exp"); hudAvatarImage = FindComponent(hudView, "Img_AvatarIcon"); ArrangeAvatarIconBehindFrame(hudView); hudExpTrack = FindRect(hudView, "Img_ExpBg"); hudExpFill = FindRect(hudView, "Img_ExpFill"); } private void BindHudEvents() { Button button = FindComponent