90 lines
2.6 KiB
C#
90 lines
2.6 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using System.Threading;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
|
|
namespace RR.UI
|
|
{
|
|
public class CounterTMP : MonoBehaviour
|
|
{
|
|
[SerializeField] protected TextMeshProUGUI countLabel;
|
|
|
|
[Header("Настройки анимации")]
|
|
[SerializeField] private int scorePerSecond = 300;
|
|
[SerializeField] private float maxAnimationTime = 2;
|
|
[SerializeField] private string countFormat = "D4";
|
|
|
|
private CancellationTokenSource animationCts;
|
|
[field: SerializeField] public int Count { get; private set; }
|
|
|
|
public void Add(int value)
|
|
{
|
|
var oldCount = Count;
|
|
Count += value;
|
|
OnNewCount(oldCount, Count);
|
|
}
|
|
|
|
public void SetCount(int value)
|
|
{
|
|
var oldCount = Count;
|
|
Count = value;
|
|
OnNewCount(oldCount, Count);
|
|
}
|
|
|
|
public void ResetCount()
|
|
{
|
|
var oldCount = Count;
|
|
Count = 0;
|
|
OnNewCount(oldCount, Count);
|
|
}
|
|
|
|
protected virtual void OnNewCount(int oldCount, int newCount)
|
|
{
|
|
countLabel.text = newCount.ToString(countFormat);
|
|
if(scorePerSecond > 0)
|
|
{
|
|
AnimateScoreChange(oldCount, newCount).Forget();
|
|
}
|
|
}
|
|
|
|
private async UniTaskVoid AnimateScoreChange(int startScore, int endScore)
|
|
{
|
|
CancelAnimation();
|
|
animationCts = new();
|
|
|
|
int scoreDifference = endScore - startScore;
|
|
float animationTime = scoreDifference / scorePerSecond;
|
|
animationTime = Mathf.Clamp(animationTime, 0.1f, maxAnimationTime);
|
|
|
|
float elapsedTime = 0f;
|
|
while (elapsedTime < animationTime && !animationCts.Token.IsCancellationRequested)
|
|
{
|
|
await UniTask.Yield(animationCts.Token);
|
|
|
|
elapsedTime += Time.deltaTime;
|
|
float t = elapsedTime / animationTime;
|
|
t = Mathf.SmoothStep(0, 1, t);
|
|
|
|
int newScore = Mathf.RoundToInt(Mathf.Lerp(startScore, endScore, t));
|
|
countLabel.text = newScore.ToString("D4");
|
|
|
|
}
|
|
countLabel.text = endScore.ToString(countFormat);
|
|
}
|
|
|
|
private void CancelAnimation()
|
|
{
|
|
if (animationCts != null)
|
|
{
|
|
animationCts.Cancel();
|
|
animationCts.Dispose();
|
|
animationCts = null;
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
CancelAnimation();
|
|
}
|
|
}
|
|
} |