using System; using Unity.Netcode; using TMPro; using UnityEngine; public class SynchronizedTimer : NetworkBehaviour { public event Action OnTimerEnd; // Ensure it's public [SerializeField] private TextMeshProUGUI timerText; // Reference to the TextMeshProUGUI component private NetworkVariable timer = new NetworkVariable(0f, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); private bool isTimerRunning = false; void Update() { if (IsServer && isTimerRunning) { // Decrease the timer only on the server timer.Value -= Time.deltaTime; if (timer.Value <= 0) { timer.Value = 0; isTimerRunning = false; OnTimerEnd?.Invoke(); // Trigger the event on the server } } // Update the UI on all clients UpdateTimerUI(); } /// /// Starts the timer. /// /// The duration of the timer in seconds. [ServerRpc(RequireOwnership = false)] public void StartTimerServerRpc(float time) { if (!isTimerRunning) { timer.Value = time; isTimerRunning = true; } } /// /// Gets the remaining time on the timer. /// /// The remaining time in seconds. public float GetRemainingTime() { return timer.Value; } // This method ensures the timer stays synchronized for clients private void OnEnable() { timer.OnValueChanged += OnTimerValueChanged; } private void OnDisable() { timer.OnValueChanged -= OnTimerValueChanged; } private void OnTimerValueChanged(float oldValue, float newValue) { if (!IsServer && newValue <= 0 && oldValue > 0) { OnTimerEnd?.Invoke(); // Trigger the event on clients when timer reaches zero } } /// /// Updates the TextMeshProUGUI with the remaining time. /// private void UpdateTimerUI() { if (timerText != null) { int minutes = Mathf.FloorToInt(timer.Value / 60); int seconds = Mathf.FloorToInt(timer.Value % 60); timerText.text = $"{minutes:D2}:{seconds:D2}"; } } }