2026-05-22 17:45:31 +03:00

81 lines
2.2 KiB
C#

using TMPro;
using UnityEngine;
using Cysharp.Threading.Tasks;
using System.Threading;
using UnityEngine.UI;
public class LetterSlot : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI _label;
[SerializeField] private Image _image;
[Header("Анимация выбора")]
[SerializeField] private float _normalScale = 1f;
[SerializeField] private float _selectedScale = 1.1f;
[SerializeField] private float _animationSpeed = 5f;
[SerializeField] private Color _selectedColor;
[SerializeField] private AnimationCurve _animationCurve;
private char _symbol;
private Color _cachedColor;
private CancellationTokenSource _cts;
public void Init(char symbol, bool selected)
{
_cachedColor = _image.color;
SetSymbol(symbol);
SetSelected(selected);
}
public void SetSelected(bool value)
{
_cts?.Cancel();
_cts?.Dispose();
_cts = new CancellationTokenSource();
AnimAsync(selected: value, _cts.Token).Forget();
}
public char GetSymbol() => _symbol;
public void SetSymbol(char symbol)
{
_symbol = symbol;
UpdateLabel();
}
private void UpdateLabel() => _label.text = _symbol.ToString();
private async UniTask AnimAsync(bool selected, CancellationToken token)
{
Color startColor = _image.color;
float startScale = transform.localScale.x;
Color targetColor = selected ? _selectedColor : _cachedColor;
float targetScale = selected ? _selectedScale : _normalScale;
float t = 0;
while (t < 1f && !token.IsCancellationRequested)
{
float t1 = _animationCurve.Evaluate(t);
transform.localScale = Vector3.one * Mathf.Lerp(startScale, targetScale, t1);
_image.color = Color.Lerp(startColor, targetColor, t1);
t += Time.deltaTime * _animationSpeed;
t = Mathf.Min(t, 1f);
await UniTask.Yield(PlayerLoopTiming.Update, token);
}
transform.localScale = Vector3.one * targetScale;
_image.color = targetColor;
}
private void OnDestroy()
{
_cts?.Cancel();
_cts?.Dispose();
}
}