using System; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Serialization; public class Timer : MonoBehaviour { public event Action TimerEnded; public UnityEvent OnTimerEnded; [FormerlySerializedAs("TimeLabel")] public TextMeshProUGUI timeLabel; [SerializeField, FormerlySerializedAs("restTime")] private float _restTime; [SerializeField] private AudioClip _warningSound; private bool _processing; private bool _recentlyPlayed; private float _lastSignalTime; private int _lastDisplayedSecond; public float RemainingTime => _restTime; public bool IsRunning => _processing; private void Update() { if (_processing == false) return; _restTime -= Time.deltaTime; if (_restTime <= 0f) { _restTime = 0f; UiDraw(); StopTimer(); TimerEnded?.Invoke(); OnTimerEnded?.Invoke(); return; } UiDraw(); int rest = Mathf.CeilToInt(_restTime); bool warningTime = rest > 0 && (rest % 60 == 0 || rest == 30 || rest < 11); if (rest != _lastDisplayedSecond && _recentlyPlayed == false && warningTime) { if (_warningSound != null) SoundManager.instance.PlaySfx(_warningSound); _recentlyPlayed = true; _lastSignalTime = Time.time; } _lastDisplayedSecond = rest; if (_recentlyPlayed && Time.time - _lastSignalTime >= 1f) _recentlyPlayed = false; } public void SetupTimer(float seconds) { _processing = false; _restTime = Mathf.Max(seconds, 0f); _recentlyPlayed = false; _lastDisplayedSecond = Mathf.CeilToInt(_restTime); UiDraw(); } public void StartTimer() => _processing = true; public void StopTimer() => _processing = false; public void StopAndReset() => SetupTimer(0f); private void UiDraw() { int totalSeconds = Mathf.CeilToInt(_restTime); int minutes = totalSeconds / 60; int seconds = totalSeconds % 60; timeLabel.text = $"{minutes:00}:{seconds:00}"; } }