using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; [RequireComponent(typeof(RectTransform))] public class SelectableButton : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler { public enum Colors { NormalColor, HighlightedColor, PressedColor, SelectedColor, DisabledColor } [SerializeField] private List graphics; [SerializeField] private bool selectedOnStart; [SerializeField, ReadOnly] private bool isSelected; [SerializeField] private UnityEvent onSelect; [SerializeField] private UnityEvent onDeselect; private GameObject parent => transform.parent.gameObject; [SerializeField] private bool interactable = true; public UnityEvent OnSelect => onSelect; public UnityEvent OnDeselect => onDeselect; public bool IsSelected => isSelected; private void Awake() { foreach (GraphicNode graphic in graphics) { graphic.targetGraphic.gameObject.SetActive(true); } if (selectedOnStart) { isSelected = true; } else { CrossFadeColor(Colors.NormalColor, true); } } private void OnEnable() { if (isSelected) CrossFadeColor(Colors.SelectedColor, true); } public void OnPointerClick(PointerEventData eventData) { Select(); } private void CrossFadeColor(Colors colors, bool instant) { foreach (GraphicNode graphic in graphics) { Color color = colors switch { Colors.NormalColor => graphic.colors.normalColor, Colors.HighlightedColor => graphic.colors.highlightedColor, Colors.PressedColor => graphic.colors.pressedColor, Colors.SelectedColor => graphic.colors.selectedColor, Colors.DisabledColor => graphic.colors.disabledColor, _ => graphic.colors.normalColor, }; graphic.targetGraphic.CrossFadeColor(color, instant ? 0f : graphic.colors.fadeDuration, true, true); } } public void Select(bool instant = false) { if (isSelected || !interactable) return; isSelected = true; CrossFadeColor(Colors.SelectedColor, instant); foreach (SelectableButton button in parent.GetComponentsInChildren()) { if(button != this && button.isSelected) { button.Deselect(); } } onSelect?.Invoke(); } public void InvokeSelectEvent() { if (isSelected) onSelect?.Invoke(); } public void Deselect(bool instant = false) { isSelected = false; CrossFadeColor(Colors.NormalColor, instant); onDeselect?.Invoke(); } public void SetIteractable(bool value) { interactable = value; if (interactable) { CrossFadeColor(isSelected ? Colors.SelectedColor : Colors.NormalColor, true); } else { CrossFadeColor(Colors.DisabledColor, true); } } public void OnPointerEnter(PointerEventData eventData) { if (isSelected || !interactable) return; CrossFadeColor(Colors.HighlightedColor, false); } public void OnPointerExit(PointerEventData eventData) { if (isSelected || !interactable) return; CrossFadeColor(Colors.NormalColor, false); } }