Danro/Assets/Scripts/UI/TextSplash.cs
Danil Iarosh a66aa2cb83 feat: Add display customization for balance and main menu texts
- Добавлена система анимированных текстовых сплешей (TextSplash) с настройками масштаба, покачивания, движения и цвета
- Добавлена поддержка циклического воспроизведения анимации сплешей
- Добавлена настройка частоты покачивания для более плавной и непрерывной анимации
- Добавлено отображение валюты в компоненте BalanceDisplay (берется из настройки payment.currency)
- Добавлены поля для отображения номера поддержки и суперприза в главном меню
- Добавлена возможность форматирования текстов через string.Format в MainMenu (supportNumberFormat, superPrizeFormat)
- Валюта и тексты автоматически обновляются при изменении настроек
2026-02-12 16:58:49 +03:00

183 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using TMPro;
using UnityEngine;
namespace RR.Common.UI
{
/// <summary>
/// Компонент для создания анимированного сплеша текста.
/// Поддерживает изменение размера, покачивание и изменение цвета.
/// </summary>
[RequireComponent(typeof(TextMeshProUGUI))]
public class TextSplash : MonoBehaviour
{
[Header("Настройки масштаба")]
[SerializeField] private bool animateScale = true;
[SerializeField] private AnimationCurve scaleCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
[SerializeField] private float startScale = 0.5f;
[SerializeField] private float endScale = 1.5f;
[Header("Настройки покачивания")]
[SerializeField] private bool animateSwing = true;
[SerializeField] private float swingAmplitude = 20f;
[SerializeField] private float swingFrequency = 2f;
[SerializeField] private AnimationCurve swingCurve = AnimationCurve.EaseInOut(0, 0, 0.5f, 1);
[Header("Настройки цвета")]
[SerializeField] private bool animateColor = true;
[SerializeField] private Gradient colorGradient = new Gradient();
[Header("Настройки движения")]
[SerializeField] private bool animateMovement = true;
[SerializeField] private Vector2 movementDirection = Vector2.up;
[SerializeField] private float movementDistance = 100f;
[SerializeField] private AnimationCurve movementCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
[Header("Общие настройки")]
[SerializeField] private float animationDuration = 1f;
[SerializeField] private bool loopAnimation = false;
[SerializeField] private bool destroyOnComplete = true;
private TextMeshProUGUI _textComponent;
private RectTransform _rectTransform;
private Vector2 _startPosition;
private float _elapsed;
private bool _isAnimating;
private void Awake()
{
_textComponent = GetComponent<TextMeshProUGUI>();
_rectTransform = GetComponent<RectTransform>();
_startPosition = _rectTransform.anchoredPosition;
}
private void OnEnable()
{
StartAnimation();
}
/// <summary>
/// Запускает анимацию сплеша
/// </summary>
public void StartAnimation()
{
_elapsed = 0f;
_isAnimating = true;
_startPosition = _rectTransform.anchoredPosition;
}
/// <summary>
/// Устанавливает текст сплеша
/// </summary>
public void SetText(string text)
{
if (_textComponent != null)
{
_textComponent.text = text;
}
}
/// <summary>
/// Устанавливает начальный цвет
/// </summary>
public void SetColor(Color color)
{
if (_textComponent != null)
{
_textComponent.color = color;
}
}
private void Update()
{
if (!_isAnimating) return;
_elapsed += Time.unscaledDeltaTime;
float t = Mathf.Clamp01(_elapsed / animationDuration);
// Анимация масштаба
if (animateScale)
{
float scaleValue = Mathf.Lerp(startScale, endScale, scaleCurve.Evaluate(t));
_rectTransform.localScale = Vector3.one * scaleValue;
}
// Анимация покачивания (rotation)
if (animateSwing)
{
float swingValue = swingCurve.Evaluate(t) * swingAmplitude;
// Используем частоту для создания непрерывного покачивания
float swingAngle = Mathf.Sin(t * Mathf.PI * 2 * swingFrequency) * swingValue;
_rectTransform.localRotation = Quaternion.Euler(0, 0, swingAngle);
}
// Анимация движения
if (animateMovement)
{
float moveValue = movementCurve.Evaluate(t) * movementDistance;
Vector2 offset = movementDirection.normalized * moveValue;
_rectTransform.anchoredPosition = _startPosition + offset;
}
// Анимация цвета
if (animateColor && _textComponent != null)
{
_textComponent.color = colorGradient.Evaluate(t);
}
// Завершение анимации
if (t >= 1f)
{
if (loopAnimation)
{
// Перезапускаем анимацию с начала
_elapsed = 0f;
}
else
{
_isAnimating = false;
if (destroyOnComplete)
{
Destroy(gameObject);
}
}
}
}
/// <summary>
/// Устанавливает длительность анимации
/// </summary>
public void SetDuration(float duration)
{
animationDuration = duration;
}
/// <summary>
/// Останавливает анимацию
/// </summary>
public void StopAnimation()
{
_isAnimating = false;
}
#if UNITY_EDITOR
/// <summary>
/// Предварительный просмотр в редакторе
/// </summary>
private void OnValidate()
{
if (colorGradient == null || colorGradient.colorKeys.Length == 0)
{
// Устанавливаем градиент по умолчанию (белый -> прозрачный)
colorGradient = new Gradient();
colorGradient.SetKeys(
new[] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) },
new[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0f, 1f) }
);
}
}
#endif
}
}