- 7 generated icons (settings, statistics, paint, freecam, thirdperson, firstperson v3 viewfinder, spectator eye) + hand-painted hover ring, full-res PNGs imported as sprites (max size 256) - Icon Background texture (user asset) - IconButtonHover: shows the Hover child on pointer hover or while the button is non-interactable (doubles as active-mode marker) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
1.5 KiB
C#
52 lines
1.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// Shows the hover overlay child of an icon button while the pointer is over
|
|
/// the button or while the button is not interactable (marks the active mode).
|
|
/// </summary>
|
|
public class IconButtonHover : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
[SerializeField, Tooltip("Overlay object toggled on hover / while the button is disabled.")]
|
|
private GameObject hover;
|
|
|
|
[SerializeField, Tooltip("Button whose interactable state drives the disabled case. Defaults to the Button on this object.")]
|
|
private Button button;
|
|
|
|
private bool _pointerInside;
|
|
|
|
private void Awake()
|
|
{
|
|
if (!button) button = GetComponent<Button>();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_pointerInside = false;
|
|
Refresh();
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
_pointerInside = true;
|
|
Refresh();
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
_pointerInside = false;
|
|
Refresh();
|
|
}
|
|
|
|
// Poll each frame: Button has no event for interactable changes (OverviewMenu
|
|
// flips it on refresh), and this only runs on a handful of menu buttons.
|
|
private void LateUpdate() => Refresh();
|
|
|
|
private void Refresh()
|
|
{
|
|
bool want = _pointerInside || (button && !button.interactable);
|
|
if (hover && hover.activeSelf != want) hover.SetActive(want);
|
|
}
|
|
}
|