using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System; using System.Collections; // Holds a graphic target with its own normal and highlighted colors [Serializable] public class TargetColorPair { public Graphic Target; public Color NormalColor = Color.white; public Color HighlightedColor = Color.grey; } public class MultiTargetButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler, ISelectHandler, IDeselectHandler { public TargetColorPair[] Targets; public float FadeDuration = 0.15f; // When enabled, the last hovered button stays highlighted // until another button takes over (mouse or gamepad) public bool PersistLastHovered = false; // Static so all instances share the same "last hovered" reference private static MultiTargetButton _lastHovered; void Awake() { foreach (var t in Targets) t.Target.color = t.NormalColor; } void SetHighlight(bool highlighted) { foreach (var t in Targets) StartCoroutine(FadeTo(t.Target, highlighted ? t.HighlightedColor : t.NormalColor)); } // Lerps color over FadeDuration — stops any previous coroutine implicitly // since we start a new one on the same graphic each time IEnumerator FadeTo(Graphic graphic, Color target) { Color start = graphic.color; float elapsed = 0f; while (elapsed < FadeDuration) { elapsed += Time.deltaTime; graphic.color = Color.Lerp(start, target, elapsed / FadeDuration); yield return null; } graphic.color = target; } // Shared logic for both mouse enter and gamepad select — // steals persistence from whoever had it before void Activate() { if (PersistLastHovered && _lastHovered != null && _lastHovered != this) _lastHovered.SetHighlight(false); SetHighlight(true); if (PersistLastHovered) _lastHovered = this; } // Mouse public void OnPointerEnter(PointerEventData e) => Activate(); public void OnPointerExit(PointerEventData e) { // If persist is on, do nothing on exit — next Activate() will clean up if (!PersistLastHovered) SetHighlight(false); } public void OnPointerClick(PointerEventData e) { } // Gamepad / keyboard — mirrors exact same logic as mouse public void OnSelect(BaseEventData e) => Activate(); public void OnDeselect(BaseEventData e) { if (!PersistLastHovered) SetHighlight(false); } public static void ClearPersistence() { if (_lastHovered != null) { _lastHovered.StopAllCoroutines(); foreach (var t in _lastHovered.Targets) t.Target.color = t.NormalColor; _lastHovered = null; } } }