Files
aibis-dream/Assets/Scripts/Framework/OtherKit/SpriteButton.cs
T
2025-08-12 17:33:05 +08:00

103 lines
3.1 KiB
C#

using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace AibisDream
{
[RequireComponent(typeof(Collider2D))]
public class SpriteButton : MonoBehaviour, IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler
{
[SerializeField] private SpriteRenderer spriteRenderer;
[SerializeField] private ColorBlock colorBlock;
public event Action OnClicked;
private bool _isPointerInside;
private bool _isPointerDown;
private bool _hasSelection;
private bool _isInteractable;
private SelectionType CurrentSelectionType
{
get
{
if (!_isInteractable)
return SelectionType.Disabled;
if (_isPointerDown)
return SelectionType.Pressed;
if (_isPointerInside)
return SelectionType.Highlighted;
return SelectionType.Normal;
}
}
public bool IsInteractive
{
get => _isInteractable;
set
{
_isInteractable = value;
DoStateTransition(CurrentSelectionType);
}
}
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
_isPointerDown = true;
EvaluateAndTransitionToSelectionType();
OnClicked?.Invoke();
}
public void OnPointerUp(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
return;
_isPointerDown = false;
EvaluateAndTransitionToSelectionType();
}
public void OnPointerEnter(PointerEventData eventData)
{
_isPointerInside = true;
EvaluateAndTransitionToSelectionType();
}
public void OnPointerExit(PointerEventData eventData)
{
_isPointerInside = false;
EvaluateAndTransitionToSelectionType();
}
private void EvaluateAndTransitionToSelectionType()
{
if (!_isInteractable)
return;
DoStateTransition(CurrentSelectionType);
}
private void DoStateTransition(SelectionType selectionType)
{
if (!gameObject.activeInHierarchy)
return;
var tintColor = selectionType switch
{
SelectionType.Normal => colorBlock.normalColor,
SelectionType.Highlighted => colorBlock.highlightedColor,
SelectionType.Pressed => colorBlock.pressedColor,
SelectionType.Selected => colorBlock.selectedColor,
SelectionType.Disabled => colorBlock.disabledColor,
_ => Color.black
};
spriteRenderer.DOColor(tintColor, colorBlock.fadeDuration).SetUpdate(true);
}
}
}