70 lines
2.1 KiB
C#
70 lines
2.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
|
|
public class RespawnCountdownUI : MonoBehaviour
|
|
{
|
|
[Header("Refs")]
|
|
[SerializeField] private GameObject root; // DeathOverlayRoot
|
|
[SerializeField] private TMP_Text titleText; // "DEAD"
|
|
[SerializeField] private TMP_Text countdownText;
|
|
[SerializeField] private Image radialFill; // Filled Image (Radial)
|
|
|
|
[Header("Text")]
|
|
[SerializeField] private string title = "DEAD";
|
|
[SerializeField] private string countdownFormat = "Respawn in {0}";
|
|
|
|
private bool _running;
|
|
private double _endServerTime;
|
|
private float _duration;
|
|
|
|
// 외부에서 호출: 사망 시 UI 시작
|
|
public void Show(double respawnEndServerTime, float durationSeconds)
|
|
{
|
|
_endServerTime = respawnEndServerTime;
|
|
_duration = Mathf.Max(0.01f, durationSeconds);
|
|
|
|
titleText.text = title;
|
|
root.SetActive(true);
|
|
_running = true;
|
|
|
|
// 초기값
|
|
SetVisual(remainingSeconds: (float)_duration);
|
|
}
|
|
|
|
// 외부에서 호출: 리스폰 완료 시 UI 종료
|
|
public void Hide()
|
|
{
|
|
_running = false;
|
|
root.SetActive(false);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!_running) return;
|
|
|
|
// 서버 기준 시간 사용 (Netcode 기준)
|
|
// 만약 ServerTime이 없다면, "서버가 remainingSeconds를 주기적으로 보내는 방식"으로 대체 가능.
|
|
double now = Unity.Netcode.NetworkManager.Singleton.ServerTime.Time;
|
|
float remaining = (float)(_endServerTime - now);
|
|
|
|
if (remaining <= 0f)
|
|
{
|
|
// 0초 도달: UI는 즉시 숨기거나, 리스폰 이벤트에서 Hide() 호출하도록 둘 중 택1
|
|
SetVisual(0f);
|
|
return;
|
|
}
|
|
|
|
SetVisual(remaining);
|
|
}
|
|
|
|
private void SetVisual(float remainingSeconds)
|
|
{
|
|
int sec = Mathf.CeilToInt(Mathf.Max(0f, remainingSeconds));
|
|
countdownText.text = string.Format(countdownFormat, sec);
|
|
|
|
// 1 -> 0으로 감소하는 연출
|
|
float t = Mathf.Clamp01(remainingSeconds / _duration);
|
|
if (radialFill != null) radialFill.fillAmount = t;
|
|
}
|
|
} |