Files
Colosseum/Assets/Scripts/UI/AbnormalitySlotUI.cs
dal4segno 3d3591784f [UI] 이상 상태 슬롯 UI 개선
- 지속 시간 표시가 주기적으로 업데이트되도록 수정
- fill 이미지가 시간이 지날수록 채워지도록 변경
- 남은 시간 정수로만 표시
- 비활성화된 Cooltime 요소 자동 활성화
- Animator Controller 제거로 UI 정상 표시

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 02:40:44 +09:00

153 lines
5.4 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Colosseum.Abnormalities;
namespace Colosseum.UI
{
/// <summary>
/// 개별 이상 상태 UI 슬롯
/// 버프/디버프 아이콘, 지속 시간 등을 표시합니다.
/// </summary>
public class AbnormalitySlotUI : MonoBehaviour
{
[Header("UI References")]
[Tooltip("이상 상태 아이콘")]
[SerializeField] private Image iconImage;
[Tooltip("지속 시간 채우기 이미지 (시계 방향)")]
[SerializeField] private Image durationFill;
[Tooltip("남은 시간 텍스트")]
[SerializeField] private TMP_Text durationText;
[Tooltip("효과 이름 텍스트")]
[SerializeField] private TMP_Text effectNameText;
[Tooltip("배경 이미지 (버프/디버프 구분용)")]
[SerializeField] private Image backgroundImage;
[Header("Colors")]
[Tooltip("버프 배경 색상")]
[SerializeField] private Color buffColor = new Color(0.2f, 0.6f, 0.2f, 0.8f);
[Tooltip("디버프 배경 색상")]
[SerializeField] private Color debuffColor = new Color(0.6f, 0.2f, 0.2f, 0.8f);
private ActiveAbnormality trackedAbnormality;
/// <summary>
/// 추적 중인 활성 이상 상태
/// </summary>
public ActiveAbnormality TrackedAbnormality => trackedAbnormality;
/// <summary>
/// UI 초기화
/// </summary>
/// <param name="abnormality">표시할 활성 이상 상태</param>
public void Initialize(ActiveAbnormality abnormality)
{
trackedAbnormality = abnormality;
if (abnormality?.Data == null)
{
Debug.LogWarning("[AbnormalitySlotUI] Initialize called with null abnormality or data");
return;
}
Debug.Log($"[AbnormalitySlotUI] Initialize: {abnormality.Data.abnormalityName}, icon: {abnormality.Data.icon?.name ?? "null"}");
Debug.Log($"[AbnormalitySlotUI] UI References - iconImage: {(iconImage != null ? "OK" : "NULL")}, durationFill: {(durationFill != null ? "OK" : "NULL")}, durationText: {(durationText != null ? "OK" : "NULL")}, backgroundImage: {(backgroundImage != null ? "OK" : "NULL")}");
// Cooltime 요소 활성화 (부모 게임오브젝트들이 비활성화되어 있을 수 있음)
EnableDurationElements();
// 아이콘 설정
if (iconImage != null)
{
iconImage.sprite = abnormality.Data.icon;
iconImage.enabled = abnormality.Data.icon != null;
}
// 이름 설정
if (effectNameText != null)
{
effectNameText.text = abnormality.Data.abnormalityName;
}
else
{
Debug.LogWarning("[AbnormalitySlotUI] effectNameText is null");
}
// 배경 색상 설정 (버프/디버프 구분)
if (backgroundImage != null)
{
backgroundImage.color = abnormality.Data.isDebuff ? debuffColor : buffColor;
}
// 초기 상태 업데이트
UpdateDisplay(abnormality.RemainingDuration, abnormality.Data.duration);
}
/// <summary>
/// UI 표시 업데이트
/// </summary>
/// <param name="remainingDuration">남은 지속 시간</param>
/// <param name="totalDuration">전체 지속 시간</param>
public void UpdateDisplay(float remainingDuration, float totalDuration)
{
// 지속 시간 채우기 이미지 업데이트 (시간이 지날수록 채워짐)
if (durationFill != null && totalDuration > 0)
{
durationFill.fillAmount = 1f - (remainingDuration / totalDuration);
}
// 남은 시간 텍스트 업데이트 (정수만 표시)
if (durationText != null)
{
if (remainingDuration > 60f)
{
durationText.text = $"{(int)(remainingDuration / 60f)}:{(int)(remainingDuration % 60f):D2}";
}
else if (remainingDuration > 0f)
{
durationText.text = $"{Mathf.CeilToInt(remainingDuration)}";
}
else
{
durationText.text = string.Empty;
}
}
}
/// <summary>
/// 지속 시간 관련 UI 요소들의 부모 게임오브젝트를 활성화합니다.
/// </summary>
private void EnableDurationElements()
{
// durationFill의 모든 부모 게임오브젝트 활성화
if (durationFill != null)
{
Transform parent = durationFill.transform.parent;
while (parent != null && parent != transform)
{
parent.gameObject.SetActive(true);
parent = parent.parent;
}
}
// durationText의 모든 부모 게임오브젝트 활성화
if (durationText != null)
{
Transform parent = durationText.transform.parent;
while (parent != null && parent != transform)
{
parent.gameObject.SetActive(true);
parent = parent.parent;
}
}
}
}
}