sega ec0920350d Обновить интерфейс настройки призов и исправить их добавление
Использовать полную иконку персонажа и крестик для пустого приза.
Добавить звук переключения, указатели выбора и анимацию добавленных призов за 0,3 секунды.
Скрывать экран настроек на время работы с конфигуратором призов.
Восстановить ссылку на префаб добавленного приза и оформить контекстные окна по макетам.
Устранить повторное подтверждение QR-приза и исправить направление вертикальной навигации витрины.

Проверено в Unity в режиме игры: ввод и сохранение значений, добавление и удаление пяти типов призов, анимация выбора и защита от повторного добавления. Ошибок в консоли нет.
2026-09-18 13:24:45 +03:00

134 lines
5.3 KiB
C#

using DG.Tweening;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public sealed class AddedPrizeButton : PrizeButton
{
private const float TransitionDuration = 0.3f;
[SerializeField] private PrizeButton _notSelectedTemplate;
[SerializeField] private PrizeButton _selectedTemplate;
private RectTransform _buttonRect;
private RectTransform _backgroundRect;
private Image _backgroundImage;
private RectTransform _iconRect;
private RectTransform _labelRect;
private RectTransform _pointerRect;
private Image _pointerImage;
private Image _deleteSignImage;
private VisualState _notSelectedState;
private VisualState _selectedState;
private Sequence _selectionTween;
private bool _isSelected;
private struct VisualState
{
public Vector2 ButtonSize;
public Vector2 BackgroundPosition;
public Vector2 BackgroundSize;
public Color BackgroundColor;
public Vector2 IconPosition;
public Vector2 IconSize;
public Vector2 LabelPosition;
public Vector2 LabelSize;
public Vector2 PointerPosition;
public TextWrappingModes TextWrappingMode;
}
private void Awake()
{
_buttonRect = (RectTransform)transform;
_backgroundRect = (RectTransform)transform.Find("bg");
_backgroundImage = _backgroundRect.GetComponent<Image>();
_iconRect = (RectTransform)_image.transform;
_labelRect = _textMeshPro.rectTransform;
_pointerRect = (RectTransform)transform.Find("pointer");
_pointerImage = _pointerRect.GetComponent<Image>();
_deleteSignImage = transform.Find("delete sign").GetComponent<Image>();
_notSelectedState = ReadState(_notSelectedTemplate);
_selectedState = ReadState(_selectedTemplate);
_deleteSignImage.raycastTarget = false;
ApplyState(_notSelectedState);
SetAlpha(_pointerImage, 0f);
SetAlpha(_deleteSignImage, 0f);
}
public override void SetSelected(bool selected)
{
if (_isSelected == selected)
return;
_isSelected = selected;
_selectionTween?.Kill();
VisualState state = selected ? _selectedState : _notSelectedState;
_selectionTween = DOTween.Sequence().SetUpdate(true);
_selectionTween.Join(_buttonRect.DOSizeDelta(state.ButtonSize, TransitionDuration));
_selectionTween.Join(_backgroundRect.DOAnchorPos(state.BackgroundPosition, TransitionDuration));
_selectionTween.Join(_backgroundRect.DOSizeDelta(state.BackgroundSize, TransitionDuration));
_selectionTween.Join(_backgroundImage.DOColor(state.BackgroundColor, TransitionDuration));
_selectionTween.Join(_iconRect.DOAnchorPos(state.IconPosition, TransitionDuration));
_selectionTween.Join(_iconRect.DOSizeDelta(state.IconSize, TransitionDuration));
_selectionTween.Join(_labelRect.DOAnchorPos(state.LabelPosition, TransitionDuration));
_selectionTween.Join(_labelRect.DOSizeDelta(state.LabelSize, TransitionDuration));
_selectionTween.Join(_pointerRect.DOAnchorPos(state.PointerPosition, TransitionDuration));
_selectionTween.Join(_pointerImage.DOFade(selected ? 1f : 0f, TransitionDuration));
_selectionTween.Join(_deleteSignImage.DOFade(selected ? 1f : 0f, TransitionDuration));
_selectionTween.InsertCallback(TransitionDuration * 0.5f,
() => _textMeshPro.textWrappingMode = state.TextWrappingMode);
_selectionTween.Play();
}
private void OnDestroy()
{
_selectionTween?.Kill();
}
private void ApplyState(VisualState state)
{
_buttonRect.sizeDelta = state.ButtonSize;
_backgroundRect.anchoredPosition = state.BackgroundPosition;
_backgroundRect.sizeDelta = state.BackgroundSize;
_backgroundImage.color = state.BackgroundColor;
_iconRect.anchoredPosition = state.IconPosition;
_iconRect.sizeDelta = state.IconSize;
_labelRect.anchoredPosition = state.LabelPosition;
_labelRect.sizeDelta = state.LabelSize;
_pointerRect.anchoredPosition = state.PointerPosition;
_textMeshPro.textWrappingMode = state.TextWrappingMode;
}
private static VisualState ReadState(PrizeButton template)
{
Transform root = template.transform;
RectTransform background = (RectTransform)root.Find("bg");
RectTransform icon = (RectTransform)root.Find("prizeIcon");
RectTransform label = (RectTransform)root.Find("Text (TMP)");
RectTransform pointer = (RectTransform)root.Find("pointer");
return new VisualState
{
ButtonSize = ((RectTransform)root).sizeDelta,
BackgroundPosition = background.anchoredPosition,
BackgroundSize = background.sizeDelta,
BackgroundColor = background.GetComponent<Image>().color,
IconPosition = icon.anchoredPosition,
IconSize = icon.sizeDelta,
LabelPosition = label.anchoredPosition,
LabelSize = label.sizeDelta,
PointerPosition = pointer.anchoredPosition,
TextWrappingMode = label.GetComponent<TextMeshProUGUI>().textWrappingMode
};
}
private static void SetAlpha(Image image, float alpha)
{
Color color = image.color;
color.a = alpha;
image.color = color;
}
}