using TMPro; using UnityEngine; using Cysharp.Threading.Tasks; using System.Threading; using UnityEngine.UI; public class LetterSlot : MonoBehaviour { [SerializeField] private TextMeshProUGUI _label; [Header("Анимация выбора")] [SerializeField] private float _normalScale = 1f; [SerializeField] private float _selectedScale = 1.1f; [SerializeField] private float _animationSpeed = 5f; [SerializeField] private Color normalColor; [SerializeField] private Color selectedColor; [SerializeField] private AnimationCurve _animationCurve; private char _symbol; private Color _cachedColor; private CancellationTokenSource _cts; public void Init(char symbol, bool selected) { 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 = _label.color; float startScale = transform.localScale.x; Color targetColor = selected ? selectedColor : normalColor; 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); _label.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; _label.color = targetColor; } private void OnDestroy() { _cts?.Cancel(); _cts?.Dispose(); } }