using System.Collections.Generic; using UnityEngine.Scripting.APIUpdating; using UnityEngine.XR.Interaction.Toolkit.Interactors; namespace UnityEngine.XR.Interaction.Toolkit.Interactables { /// /// An interface that represents an Interactable component which /// Interactor components can hover over. /// /// [MovedFrom("UnityEngine.XR.Interaction.Toolkit")] public interface IXRHoverInteractable : IXRInteractable { /// /// The event that is called only when the first Interactor begins hovering /// over this Interactable as the sole hovering Interactor. Subsequent Interactors that /// begin hovering over this Interactable will not cause this event to be invoked as /// long as any others are still hovering. /// /// /// The passed to each listener is only valid while the event is invoked, /// do not hold a reference to it. /// /// /// HoverEnterEvent firstHoverEntered { get; } /// /// The event that is called only when the last remaining hovering Interactor /// ends hovering over this Interactable. /// /// /// The passed to each listener is only valid while the event is invoked, /// do not hold a reference to it. /// /// /// HoverExitEvent lastHoverExited { get; } /// /// The event that is called when an Interactor begins hovering over this Interactable. /// /// /// The passed to each listener is only valid while the event is invoked, /// do not hold a reference to it. /// /// HoverEnterEvent hoverEntered { get; } /// /// The event that is called when an Interactor ends hovering over this Interactable. /// /// /// The passed to each listener is only valid while the event is invoked, /// do not hold a reference to it. /// /// HoverExitEvent hoverExited { get; } /// /// (Read Only) The list of Interactors that are hovering on this Interactable (may by empty). /// /// /// You should treat this as a read only view of the list and should not modify it. /// Unity exposes this as a rather than an to avoid /// GC Allocations when enumerating the list. /// /// /// List interactorsHovering { get; } /// /// (Read Only) Indicates whether an Interactor currently hovers over this Interactable. /// /// /// In other words, returns whether contains any interactors. /// /// /// interactorsHovering.Count > 0 /// /// /// bool isHovered { get; } /// /// Determines if a given Interactor can hover over this Interactable. /// /// Interactor to check for a valid hover state with. /// Returns if hovering is valid this frame. Returns if not. /// bool IsHoverableBy(IXRHoverInteractor interactor); /// /// The calls this method right /// before the Interactor first initiates hovering over an Interactable /// in a first pass. /// /// Event data containing the Interactor that is initiating the hover. /// /// is only valid during this method call, do not hold a reference to it. /// /// void OnHoverEntering(HoverEnterEventArgs args); /// /// The calls this method /// when the Interactor first initiates hovering over an Interactable /// in a second pass. /// /// Event data containing the Interactor that is initiating the hover. /// /// is only valid during this method call, do not hold a reference to it. /// /// void OnHoverEntered(HoverEnterEventArgs args); /// /// The calls this method /// right before the Interactor ends hovering over an Interactable /// in a first pass. /// /// Event data containing the Interactor that is ending the hover. /// /// is only valid during this method call, do not hold a reference to it. /// /// void OnHoverExiting(HoverExitEventArgs args); /// /// The calls this method /// when the Interactor ends hovering over an Interactable /// in a second pass. /// /// Event data containing the Interactor that is ending the hover. /// /// is only valid during this method call, do not hold a reference to it. /// /// void OnHoverExited(HoverExitEventArgs args); } /// /// Extension methods for . /// /// [MovedFrom("UnityEngine.XR.Interaction.Toolkit")] public static class XRHoverInteractableExtensions { /// /// Gets the oldest interactor currently hovering on this interactable. /// This is a convenience method for when the interactable does not support being hovered by multiple interactors at a time. /// /// The interactable to operate on. /// Returns the oldest interactor currently hovering on this interactable. /// /// Equivalent to interactorsHovering.Count > 0 ? interactorsHovering[0] : null /// /// public static IXRHoverInteractor GetOldestInteractorHovering(this IXRHoverInteractable interactable) => interactable?.interactorsHovering.Count > 0 ? interactable.interactorsHovering[0] : null; /// /// Gets whether the interactable is currently being hovered by an interactor associated with the left hand or controller. /// /// The interactable to operate on. /// Returns if any interactor currently hovering this interactable has of . /// /// This method will return even if it is not exclusively being hovered by the left hand or controller. /// In other words, it will still return if the interactable is also being hovered by /// an interactor associated with the right hand or controller. /// /// /// public static bool IsHoveredByLeft(this IXRHoverInteractable interactable) => IsHoveredBy(interactable, InteractorHandedness.Left); /// /// Gets whether the interactable is currently being hovered by an interactor associated with the right hand or controller. /// /// The interactable to operate on. /// Returns if any interactor currently hovering this interactable has of . /// /// This method will return even if it is not exclusively being hovered by the right hand or controller. /// In other words, it will still return if the interactable is also being hovered by /// an interactor associated with the left hand or controller. /// /// /// public static bool IsHoveredByRight(this IXRHoverInteractable interactable) => IsHoveredBy(interactable, InteractorHandedness.Right); static bool IsHoveredBy(IXRHoverInteractable interactable, InteractorHandedness handedness) { var interactorsHovering = interactable.interactorsHovering; for (var i = 0; i < interactorsHovering.Count; ++i) { if (interactorsHovering[i].handedness == handedness) return true; } return false; } } }