using System; using UnityEngine; using UnityEngine.EventSystems; namespace OmiLAXR { /// /// Handles pointer interaction events for UI elements, supporting both mouse and XR interaction. /// Implements Unity's pointer interface to track hover, press, and release events. /// public class InteractionEventHandler : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler { /// /// Contains data about the pointer interaction events. /// public struct InteractionEventArgs { /// /// Total number of presses recorded since this component was initialized. /// public int TotalPresses { get; set; } /// /// Number of presses recorded during the current hover. /// public int PressesInHover { get; set; } /// /// Duration in seconds that the pointer has been hovering over this element. /// public float HoverDuration { get; set; } /// /// Duration in seconds that the pointer has been pressing this element. /// public float PressDuration { get; set; } } // Timestamp when the pointer starts hovering over this element private float _hoverStartTime; // Timestamp when the pointer starts pressing this element private float _pressStartTime; // Flags to track the current interaction state private bool _isHovering = false; private bool _isPressing = false; // Sum of how often the button was pressed inside a hover private int _pressHoverSum = 0; private int _pressTotalSum = 0; /// /// Event triggered when the pointer starts hovering over this element. /// public event Action OnHoverStarted; /// /// Event triggered when the pointer stops hovering over this element. /// public event Action OnHoverEnded; /// /// Event triggered when the pointer begins pressing this element. /// public event Action OnPressStarted; /// /// Event triggered when the pointer releases this element after pressing. /// public event Action OnPressEnded; /// /// Event triggered when a complete click action occurs (press and release while hovering). /// Only fires when the element is released while the pointer is still hovering over it. /// public event Action OnClicked; /// /// Whether the pointer is currently hovering over this element. /// public bool IsHovering => _isHovering; /// /// Whether the pointer is currently pressing this element. /// public bool IsPressing => _isPressing; /// /// Called when the pointer enters this UI element. /// Records the start time and logs the event. /// public void OnPointerEnter(PointerEventData eventData) { _hoverStartTime = Time.time; _isHovering = true; _pressHoverSum = 0; OnHoverStarted?.Invoke(new InteractionEventArgs() { TotalPresses = _pressTotalSum, PressesInHover = _pressHoverSum, HoverDuration = 0, PressDuration = 0 }); } /// /// Called when the pointer exits this UI element. /// Calculates the hover duration, logs the event, and triggers the OnHoverEnded event. /// public void OnPointerExit(PointerEventData eventData) { if (!_isHovering) return; _isHovering = false; OnHoverEnded?.Invoke(new InteractionEventArgs() { TotalPresses = _pressTotalSum, PressesInHover = _pressHoverSum, HoverDuration = Time.time - _hoverStartTime, PressDuration = _isPressing ? Time.time - _pressStartTime : 0 }); } /// /// Called when the pointer is pressed down on this UI element. /// Records the start time and triggers the OnPressStarted event. /// public void OnPointerDown(PointerEventData eventData) { _pressStartTime = Time.time; _isPressing = true; OnPressStarted?.Invoke(new InteractionEventArgs() { TotalPresses = _pressTotalSum, PressesInHover = _pressHoverSum, HoverDuration = Time.time - _hoverStartTime, PressDuration = 0 }); } /// /// Called when the pointer is released on this UI element. /// Calculates the press duration, increments press counters, and triggers the OnPressEnded event. /// Also triggers OnClicked if the release happens while still hovering over the element. /// public void OnPointerUp(PointerEventData eventData) { if (!_isPressing) return; var pressDuration = Time.time - _pressStartTime; _isPressing = false; _pressHoverSum++; _pressTotalSum++; var eventArgs = new InteractionEventArgs() { TotalPresses = _pressTotalSum, PressesInHover = _pressHoverSum, HoverDuration = Time.time - _hoverStartTime, PressDuration = pressDuration }; OnPressEnded?.Invoke(eventArgs); // If we're still hovering when the press ends, this is considered a "click" if (_isHovering) { OnClicked?.Invoke(eventArgs); } } } }