using UnityEngine; using UnityEngine.UI; using TMPro; using Colosseum.Skills; namespace Colosseum.UI { /// /// 개별 스킬 슬롯 UI /// public class SkillSlotUI : MonoBehaviour { [Header("References")] [SerializeField] private Image iconImage; [SerializeField] private Image cooldownOverlay; [SerializeField] private TMP_Text cooldownText; [SerializeField] private TMP_Text keybindText; [Header("Settings")] [SerializeField] private Color availableColor = Color.white; [SerializeField] private Color cooldownColor = new Color(0.2f, 0.2f, 0.2f, 0.9f); [SerializeField] private Color noManaColor = new Color(0.5f, 0.2f, 0.2f, 0.8f); private SkillData skill; private int slotIndex; private bool useIconForCooldown = false; private Animator cooldownAnimator; // 쿨다운 오버레이를 제어하는 Animator private GameObject cooldownContainer; // 쿨다운 오버레이의 부모 GameObject (Cooldown) public int SlotIndex => slotIndex; private void Awake() { if (cooldownOverlay == null) { useIconForCooldown = true; } else if (cooldownOverlay.type != Image.Type.Filled) { useIconForCooldown = true; } else { // 쿨다운 오버레이의 상위 GameObject에 있는 Animator 찾기 // 구조: CooldownItem (Animator) -> Cooldown -> SPR_Cooldown (Image) cooldownAnimator = cooldownOverlay.GetComponentInParent(); // Animator가 Cooldown GameObject를 제어하므로 // 쿨다운 표시를 위해 Animator를 비활성화하고 수동으로 제어 if (cooldownAnimator != null) { cooldownAnimator.enabled = false; // Animator가 제어하던 Cooldown GameObject 찾기 // SPR_Cooldown의 부모가 Cooldown cooldownContainer = cooldownOverlay.transform.parent?.gameObject; } // 쿨다운 오버레이 초기화 cooldownOverlay.fillAmount = 0f; cooldownOverlay.enabled = false; // Cooldown 컨테이너 비활성화 if (cooldownContainer != null) { cooldownContainer.SetActive(false); } } } public void Initialize(int index, SkillData skillData, string keyLabel) { slotIndex = index; skill = skillData; if (keybindText != null) keybindText.text = keyLabel; if (skill != null && iconImage != null) { iconImage.sprite = skill.Icon; iconImage.enabled = true; iconImage.color = availableColor; } else if (iconImage != null) { iconImage.enabled = false; } Debug.Log($"[SkillSlotUI] Init slot {index}: skill={skillData?.SkillName}, useIcon={useIconForCooldown}"); } public void UpdateState(float cooldownRemaining, float cooldownTotal, bool hasEnoughMana) { if (skill == null) { if (cooldownContainer != null) cooldownContainer.SetActive(false); if (cooldownOverlay != null) cooldownOverlay.enabled = false; if (cooldownText != null) cooldownText.text = ""; return; } if (cooldownRemaining > 0f) { float ratio = cooldownRemaining / cooldownTotal; if (useIconForCooldown && iconImage != null) { // 아이콘 색상으로 쿨다운 표시 float brightness = Mathf.Lerp(0.3f, 1f, 1f - ratio); iconImage.color = new Color(brightness, brightness, brightness, 1f); } else if (cooldownOverlay != null) { // Cooldown 컨테이너 활성화 if (cooldownContainer != null && !cooldownContainer.activeSelf) { cooldownContainer.SetActive(true); } // Image 컴포넌트 활성화 cooldownOverlay.enabled = true; cooldownOverlay.fillAmount = ratio; } if (cooldownText != null) { cooldownText.text = cooldownRemaining < 1f ? $"{cooldownRemaining:F1}" : $"{Mathf.CeilToInt(cooldownRemaining)}"; } } else { // 쿨다운 완료 if (useIconForCooldown && iconImage != null) { iconImage.color = hasEnoughMana ? availableColor : noManaColor; } else if (cooldownOverlay != null) { // Image 컴포넌트 비활성화 cooldownOverlay.enabled = false; // Cooldown 컨테이너 비활성화 if (cooldownContainer != null) { cooldownContainer.SetActive(false); } } if (cooldownText != null) { cooldownText.text = ""; } } } public void SetSkill(SkillData skillData) { skill = skillData; if (skill != null && iconImage != null) { iconImage.sprite = skill.Icon; iconImage.enabled = true; iconImage.color = availableColor; } else if (iconImage != null) { iconImage.enabled = false; } } } }