Files
UnityPackages/Assets/Common/Timer/Runtime/UI/TimerDurationText.cs
2025-12-01 12:36:01 +08:00

79 lines
2.0 KiB
C#

using System;
using JoeSiu.Common.Serialization.Runtime;
using TMPro;
using TriInspector;
using UnityEditor;
using UnityEngine;
namespace Common.Timer.Runtime.UI
{
[ExecuteAlways]
public class TimerDurationText : MonoBehaviour
{
public TMP_Text text;
[SerializeField]
private SerializableInterface<ITimer> _timer = new();
#if UNITY_EDITOR
[ShowIf(nameof(IsStopwatch))]
#endif
public bool useRemainingTimeForStopwatch = true;
[Range(0, 15)]
public int precision = 0;
[Range(0, 15)]
public int padLeft = 0;
[Range(0, 15)]
public int padRight = 0;
#if UNITY_EDITOR
private bool IsStopwatch => Timer is IStopwatch;
#endif
public ITimer Timer
{
get => _timer?.Value;
set => _timer.Value = value;
}
private void Reset()
{
text = GetComponent<TMP_Text>();
}
private void OnValidate()
{
#if UNITY_EDITOR
if (!EditorApplication.isPlaying && Selection.Contains(gameObject)) UpdateText(Timer);
#endif
}
private void Update()
{
UpdateText(Timer);
}
public void UpdateText(ITimer timer)
{
if (!text) return;
if (timer == null) return;
float time;
if (useRemainingTimeForStopwatch && timer is IStopwatch stopwatch)
{
time = stopwatch.RemainingTime;
}
else
{
time = timer.CurrentTime;
}
time = (float)Math.Round(time, precision);
var timeString = time.ToString();
// TODO: PadLeft / PadRight doesn't work in all cases (e.g., given time of 1, it can't turn into 01.00)
// TODO: Use a custom user defined formatter instead?
if (padLeft > 0) timeString = timeString.PadLeft(padLeft, '0');
if (padRight > 0) timeString = timeString.PadRight(padRight, '0');
text.SetText(timeString);
}
}
}