Files
Ipseity-Demo/Packages/OctoCore/Runtime/Scripts/UI/MultiTargetButton.cs
T
2026-06-12 17:55:30 +02:00

87 lines
2.9 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
using System.Collections;
using OctoCore.Navigation;
// 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) {
if (Time.time < OctoMainMenu.IgnoreMouseUntil) return;
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;
}
}
}