- SkillSlotUI: 개별 슬롯 (아이콘, 쿨다운 오버레이, 텍스트) - SkillQuickSlotUI: 6개 슬롯 관리 및 PlayerSkillInput 연동 - Animator 제어 문제 해결: 수동 SetActive로 쿨다운 표시 - UI_Bar에 PlayerHUD, StatBar 컴포넌트 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
176 lines
6.0 KiB
C#
176 lines
6.0 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
using Colosseum.Skills;
|
|
|
|
namespace Colosseum.UI
|
|
{
|
|
/// <summary>
|
|
/// 개별 스킬 슬롯 UI
|
|
/// </summary>
|
|
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>();
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
}
|