192 lines
5.6 KiB
C#
192 lines
5.6 KiB
C#
using DG.Tweening;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using VContainer;
|
|
using WordsToolkit.Scripts.Audio;
|
|
using WordsToolkit.Scripts.Gameplay.Managers;
|
|
using WordsToolkit.Scripts.Utils;
|
|
using WordsToolkit.Scripts.System;
|
|
using WordsToolkit.Scripts.Enums;
|
|
|
|
namespace WordsToolkit.Scripts.GUI
|
|
{
|
|
[RequireComponent(typeof(TextMeshProUGUI))]
|
|
public class TimerDisplay : MonoBehaviour
|
|
{
|
|
private TextMeshProUGUI timerText;
|
|
[Inject]
|
|
private LevelManager levelManager;
|
|
[Inject]
|
|
private IAudioService audioService;
|
|
private CanvasGroup canvasGroup;
|
|
private Color originalTextColor;
|
|
[SerializeField]
|
|
private AudioClip alertSound;
|
|
|
|
private Sequence bounceSequence;
|
|
private Sequence fadeSequence;
|
|
private bool isWarningActive;
|
|
private bool isVisible = true;
|
|
|
|
private void Awake()
|
|
{
|
|
timerText = GetComponent<TextMeshProUGUI>();
|
|
canvasGroup = GetComponent<CanvasGroup>();
|
|
|
|
// Add canvas group if it doesn't exist
|
|
if (canvasGroup == null)
|
|
canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
originalTextColor = timerText.color;
|
|
EventManager.OnGameStateChanged += OnGameStateChanged;
|
|
UpdateVisibility();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
EventManager.OnGameStateChanged -= OnGameStateChanged;
|
|
|
|
if (bounceSequence != null)
|
|
{
|
|
bounceSequence.Kill();
|
|
bounceSequence = null;
|
|
}
|
|
|
|
if (fadeSequence != null)
|
|
{
|
|
fadeSequence.Kill();
|
|
fadeSequence = null;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (levelManager != null && isVisible)
|
|
{
|
|
float timeToDisplay;
|
|
bool isTimerActive = levelManager.HasTimer;
|
|
|
|
// Update timer text - display as countdown
|
|
if (levelManager.HasTimer && levelManager.TimerLimit > 0)
|
|
{
|
|
// Calculate remaining time
|
|
float remainingTime = Mathf.Max(0, levelManager.TimerLimit - levelManager.GameTime);
|
|
timerText.text = TimeUtils.GetTimeString(remainingTime);
|
|
timeToDisplay = remainingTime;
|
|
}
|
|
else
|
|
{
|
|
// For timers without limits, just show elapsed time
|
|
timerText.text = TimeUtils.GetTimeString(levelManager.GameTime);
|
|
timeToDisplay = levelManager.GameTime;
|
|
}
|
|
|
|
if (timeToDisplay <= 10f && !isWarningActive && isTimerActive)
|
|
{
|
|
StartWarningEffect();
|
|
}
|
|
else if (timeToDisplay > 10f && isWarningActive)
|
|
{
|
|
StopWarningEffect();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnGameStateChanged(EGameState newState)
|
|
{
|
|
UpdateVisibility();
|
|
}
|
|
|
|
private void UpdateVisibility()
|
|
{
|
|
bool shouldBeVisible = levelManager.HasTimer && EventManager.GameStatus <= EGameState.Playing;
|
|
|
|
if (shouldBeVisible && !isVisible)
|
|
{
|
|
ShowTimer();
|
|
}
|
|
else if (!shouldBeVisible && isVisible)
|
|
{
|
|
HideTimer();
|
|
}
|
|
}
|
|
|
|
private void ShowTimer()
|
|
{
|
|
if (fadeSequence != null)
|
|
{
|
|
fadeSequence.Kill();
|
|
fadeSequence = null;
|
|
}
|
|
|
|
isVisible = true;
|
|
canvasGroup.interactable = true;
|
|
canvasGroup.blocksRaycasts = true;
|
|
|
|
fadeSequence = DOTween.Sequence();
|
|
fadeSequence.Append(canvasGroup.DOFade(1f, 0.3f));
|
|
}
|
|
|
|
private void HideTimer()
|
|
{
|
|
if (fadeSequence != null)
|
|
{
|
|
fadeSequence.Kill();
|
|
fadeSequence = null;
|
|
}
|
|
|
|
isVisible = false;
|
|
|
|
fadeSequence = DOTween.Sequence();
|
|
fadeSequence.Append(canvasGroup.DOFade(0f, 0.5f));
|
|
fadeSequence.OnComplete(() =>
|
|
{
|
|
canvasGroup.interactable = false;
|
|
canvasGroup.blocksRaycasts = false;
|
|
});
|
|
}
|
|
|
|
private void StartWarningEffect()
|
|
{
|
|
if (timerText == null) return;
|
|
|
|
if (alertSound != null)
|
|
audioService.PlaySound(alertSound);
|
|
|
|
isWarningActive = true;
|
|
originalTextColor = timerText.color;
|
|
|
|
if (bounceSequence != null)
|
|
{
|
|
bounceSequence.Kill();
|
|
bounceSequence = null;
|
|
}
|
|
|
|
bounceSequence = DOTween.Sequence();
|
|
bounceSequence.Append(timerText.transform.DOScale(1.2f, 0.3f));
|
|
bounceSequence.Append(timerText.transform.DOScale(1f, 0.3f));
|
|
timerText.color = new Color32(0xF6, 0x42, 0x8E, 0xFF);
|
|
bounceSequence.SetLoops(-1);
|
|
}
|
|
|
|
private void StopWarningEffect()
|
|
{
|
|
if (timerText == null) return;
|
|
|
|
isWarningActive = false;
|
|
|
|
if (bounceSequence != null)
|
|
{
|
|
bounceSequence.Kill();
|
|
bounceSequence = null;
|
|
}
|
|
|
|
timerText.transform.localScale = Vector3.one;
|
|
timerText.color = originalTextColor;
|
|
}
|
|
|
|
}
|
|
} |