using System; using TriInspector; using UnityEngine; namespace Common.Timer.Runtime { public class MonoStopwatch : MonoTimer, IStopwatch { public override float CurrentTime { get { currentTime = Mathf.Clamp(currentTime, 0f, Duration); return currentTime; } set => currentTime = Mathf.Clamp(value, 0f, Duration); } [Title("Settings (Stopwatch)")] [SerializeField] protected float duration; [Group("Internal"), ShowInInspector, DisableInEditMode] public virtual float Duration { get { duration = Mathf.Max(0.001f, duration); return duration; } set => duration = Mathf.Max(0.001f, value); } [SerializeField] protected bool deactivateOnTimeReached; public bool DeactivateOnTimeReached { get => deactivateOnTimeReached; set => deactivateOnTimeReached = value; } [Group("Internal"), ShowInInspector, DisableInEditMode] public virtual float RemainingTime { get => Mathf.Clamp(Duration - CurrentTime, 0f, Duration); set => CurrentTime = Mathf.Clamp(Duration - value, 0f, Duration); } [Group("Internal"), ShowInInspector, DisableInEditMode] public virtual float Progress { get => Duration == 0f ? 0f : Mathf.Clamp(CurrentTime / Duration, 0f, 1f); set => CurrentTime = Mathf.Clamp(Duration * value, 0f, Duration); } [Group("Internal"), ReadOnly, ShowInInspector, DisableInEditMode] public virtual bool IsTimeReached => CurrentTime >= Duration; public event Action OnTimeReached; public override void Tick() { if (IsTimeReached) return; base.Tick(); if (!IsActive) return; if (CurrentTime >= Duration) EndTime(); } public virtual void SetDuration(float value) { Duration = value; if (IsTimeReached) EndTime(); } public virtual void SetRemainingTime(float value) { RemainingTime = value; if (IsTimeReached) EndTime(); } public virtual void SetProgress(float value) { Progress = value; if (IsTimeReached) EndTime(); } public virtual void EndTime() { currentTime = Duration; InvokeOnTimeReached(); if (DeactivateOnTimeReached) Deactivate(); } protected virtual void InvokeOnTimeReached() { OnTimeReached?.Invoke(); } #if UNITY_EDITOR [Group("Debug"), Button("End Time"), HideInEditMode] private void EndTimer_Editor() => EndTime(); #endif } }