using UnityEngine; using Colosseum.Player; using Colosseum.Skills; namespace Colosseum.UI { /// /// 스킬 퀵슬롯 UI 관리자. /// PlayerSkillInput과 연동하여 쿨타임, 마나 등을 표시합니다. /// public class SkillQuickSlotUI : MonoBehaviour { [Header("Skill Slots")] [Tooltip("6개의 스킬 슬롯 UI (인덱스 순서대로)")] [SerializeField] private SkillSlotUI[] skillSlots = new SkillSlotUI[6]; [Header("Debug")] [SerializeField] private bool debugMode = false; [Header("Keybind Labels")] [Tooltip("키바인딩 표시 텍스트 (기본: Q, W, E, R, A, S)")] [SerializeField] private string[] keyLabels = { "Q", "W", "E", "R", "A", "S" }; private PlayerSkillInput playerSkillInput; private PlayerNetworkController networkController; private void Start() { // 로컬 플레이어 찾기 FindLocalPlayer(); } private void FindLocalPlayer() { var players = FindObjectsByType(FindObjectsSortMode.None); if (players.Length == 0) { Debug.LogWarning("[SkillQuickSlotUI] No PlayerSkillInput found in scene"); return; } foreach (var player in players) { if (player.IsOwner) { playerSkillInput = player; networkController = player.GetComponent(); Debug.Log($"[SkillQuickSlotUI] Found local player: {player.name}"); InitializeSlots(); return; } } Debug.LogWarning("[SkillQuickSlotUI] No local player found (IsOwner = false)"); } private void InitializeSlots() { if (playerSkillInput == null) return; int initializedCount = 0; for (int i = 0; i < skillSlots.Length && i < keyLabels.Length; i++) { SkillData skill = playerSkillInput.GetSkill(i); string keyLabel = i < keyLabels.Length ? keyLabels[i] : (i + 1).ToString(); if (skillSlots[i] != null) { skillSlots[i].Initialize(i, skill, keyLabel); if (skill != null) initializedCount++; } else { Debug.LogWarning($"[SkillQuickSlotUI] Slot {i} is not assigned"); } } Debug.Log($"[SkillQuickSlotUI] Initialized {initializedCount} skill slots"); } private void Update() { if (playerSkillInput == null) { // 플레이어가 아직 없으면 다시 찾기 시도 FindLocalPlayer(); return; } UpdateSlotStates(); } private float debugLogTimer = 0f; private void UpdateSlotStates() { bool shouldLog = debugMode && Time.time > debugLogTimer; if (shouldLog) debugLogTimer = Time.time + 1f; for (int i = 0; i < skillSlots.Length; i++) { if (skillSlots[i] == null) continue; SkillData skill = playerSkillInput.GetSkill(i); if (skill == null) continue; float remainingCooldown = playerSkillInput.GetRemainingCooldown(i); float totalCooldown = skill.Cooldown; bool hasEnoughMana = networkController == null || networkController.Mana >= skill.ManaCost; if (shouldLog && remainingCooldown > 0f) { Debug.Log($"[SkillQuickSlotUI] Slot {i}: {skill.SkillName}, CD: {remainingCooldown:F1}/{totalCooldown:F1}"); } skillSlots[i].UpdateState(remainingCooldown, totalCooldown, hasEnoughMana); } } /// /// 플레이어 참조 수동 설정 (씬 전환 등에서 사용) /// public void SetPlayer(PlayerSkillInput player) { playerSkillInput = player; networkController = player?.GetComponent(); InitializeSlots(); } /// /// 특정 슬롯의 스킬 변경 /// public void UpdateSkillSlot(int slotIndex, SkillData skill) { if (slotIndex < 0 || slotIndex >= skillSlots.Length) return; string keyLabel = slotIndex < keyLabels.Length ? keyLabels[slotIndex] : (slotIndex + 1).ToString(); skillSlots[slotIndex].Initialize(slotIndex, skill, keyLabel); } } }