using System; using UnityEngine; using UnityEngine.EventSystems; namespace BriarQueen.UI.Menus.Components { public class AnimatedSelectionButtonGroup : MonoBehaviour { [Header("Buttons")] [SerializeField] private AnimatedSelectionButton[] _buttons = Array.Empty(); [SerializeField] private int _defaultSelectedIndex; [Header("Selection")] [SerializeField] private bool _selectDefaultOnEnable = true; [SerializeField] private bool _syncEventSystemSelection = true; public AnimatedSelectionButton Current { get; private set; } public AnimatedSelectionButton CurrentHovered { get; private set; } private void Reset() { _buttons = GetComponentsInChildren(true); } private void OnEnable() { BindButtons(); if (_selectDefaultOnEnable) SelectIndex(_defaultSelectedIndex, true); } private void OnDisable() { UnbindButtons(); CurrentHovered = null; } public void SelectIndex(int index, bool instant = false) { if (_buttons == null || _buttons.Length == 0) return; SelectButton(_buttons[Mathf.Clamp(index, 0, _buttons.Length - 1)], instant); } public void SelectButton(AnimatedSelectionButton selectedButton, bool instant = false) { if (selectedButton == null) return; if (Current == selectedButton && !instant) return; Current = selectedButton; RefreshAllButtonStates(instant); SyncEventSystemSelection(selectedButton); } // ── Internal ────────────────────────────────────────────────── private void RefreshAllButtonStates(bool instant = false) { if (_buttons == null) return; foreach (var button in _buttons) { if (button == null) continue; // A button shows its highlight if it is selected OR it is the // hovered button AND no other button is being hovered that would // take visual priority. Selected button highlight only shows when // nothing is hovered, or when it itself is hovered. var isSelected = button == Current; var isHovered = button == CurrentHovered; var showHighlight = isSelected ? CurrentHovered == null || isHovered // selected: show unless something else is hovered : isHovered; // unselected: show only if hovered button.SetHighlight(showHighlight, instant); button.SetSelectedState(isSelected); } } private void HandleSelectionRequested(AnimatedSelectionButton selectedButton) { SelectButton(selectedButton); } private void HandleHoverEntered(AnimatedSelectionButton button) { CurrentHovered = button; RefreshAllButtonStates(); } private void HandleHoverExited(AnimatedSelectionButton button) { if (CurrentHovered == button) CurrentHovered = null; RefreshAllButtonStates(); } private void BindButtons() { if (_buttons == null) return; foreach (var button in _buttons) { if (button == null) continue; button.SelectionRequested += HandleSelectionRequested; button.HoverEntered += HandleHoverEntered; button.HoverExited += HandleHoverExited; } } private void UnbindButtons() { if (_buttons == null) return; foreach (var button in _buttons) { if (button == null) continue; button.SelectionRequested -= HandleSelectionRequested; button.HoverEntered -= HandleHoverEntered; button.HoverExited -= HandleHoverExited; } } private void SyncEventSystemSelection(AnimatedSelectionButton selectedButton) { if (!_syncEventSystemSelection || selectedButton.Button == null || EventSystem.current == null) return; var selectedGameObject = selectedButton.Button.gameObject; if (EventSystem.current.currentSelectedGameObject == selectedGameObject) return; EventSystem.current.SetSelectedGameObject(selectedGameObject); } } }