83 lines
2.8 KiB
C#
83 lines
2.8 KiB
C#
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;
|
|
}
|
|
}
|
|
} |