internal void RegisterInteractor(BaseInteractor interactor)
 {
     if (!m_Interactors.Contains(interactor))
     {
         m_Interactors.Add(interactor);
     }
 }
 internal void UnregisterInteractor(BaseInteractor interactor)
 {
     if (m_Interactors.Contains(interactor))
     {
         ClearInteractorHover(interactor, null);
         m_Interactors.Remove(interactor);
     }
 }
 void ClearInteractorHover(BaseInteractor interactor, List <BaseInteractable> validTargets)
 {
     interactor.GetHoverTargets(m_HoverTargetList);
     for (int i = 0; i < m_HoverTargetList.Count; i++)
     {
         var target = m_HoverTargetList[i];
         if (!interactor.allowHover || !interactor.CanHover(target) || !target.IsHoverableBy(interactor) || (validTargets == null || !validTargets.Contains(target)))
         {
             HoverExit(interactor, target);
         }
     }
 }
        /// <summary>This method is called by the interaction manager
        /// when the interactor first initiates hovering over an interactable.</summary>
        /// <param name="interactor">Interactor that is initiating the hover.</param>
        protected internal virtual void OnHoverEnter(BaseInteractor interactor)
        {
            isHovered = true;
            m_HoveringInteractors.Add(interactor);

            if (m_HoveringInteractors.Count == 1)
            {
                m_OnFirstHoverEnter?.Invoke(interactor);
            }

            m_OnHoverEnter?.Invoke(interactor);
        }
        internal List <BaseInteractable> GetValidTargets(BaseInteractor interactor, List <BaseInteractable> validTargets)
        {
            interactor.GetValidTargets(validTargets);

            // Remove interactables that are not being handled by this manager.
            for (int i = validTargets.Count - 1; i >= 0; --i)
            {
                if (!m_Interactables.Contains(validTargets[i]))
                {
                    validTargets.RemoveAt(i);
                }
            }
            return(validTargets);
        }
        /// <summary>This method is called by the interaction manager
        /// when the interactor ends hovering over an interactable.</summary>
        /// <param name="interactor">Interactor that is ending the hover.</param>
        protected internal virtual void OnHoverExit(BaseInteractor interactor)
        {
            isHovered = false;
            if (m_HoveringInteractors.Contains(interactor))
            {
                m_HoveringInteractors.Remove(interactor);
            }

            if (m_HoveringInteractors.Count == 0)
            {
                m_OnLastHoverExit?.Invoke(interactor);
            }

            m_OnHoverExit?.Invoke(interactor);
        }
        /// <summary>
        /// Calculates distance squared to interactor (based on colliders).
        /// </summary>
        /// <param name="interactor">Interactor to calculate distance against.</param>
        /// <returns>Minimum distance between the interactor and this interactable's colliders.</returns>
        public float GetDistanceSqrToInteractor(BaseInteractor interactor)
        {
            if (!interactor)
            {
                return(float.MaxValue);
            }

            float minDistanceSqr = float.MaxValue;

            foreach (var col in m_Colliders)
            {
                var offset = (interactor.attachTransform.position - col.transform.position);
                minDistanceSqr = Mathf.Min(offset.sqrMagnitude, minDistanceSqr);
            }
            return(minDistanceSqr);
        }
 void InteractorHoverValidTargets(BaseInteractor interactor, List <BaseInteractable> validTargets)
 {
     if (interactor.allowHover)
     {
         var orderedTargets = validTargets.OrderBy(x => x.priority).ToList();
         for (var i = 0; i < orderedTargets.Count; ++i)
         {
             interactor.GetHoverTargets(m_HoverTargetList);
             if (interactor.CanHover(orderedTargets[i]) &&
                 orderedTargets[i].IsHoverableBy(interactor) &&
                 !m_HoverTargetList.Contains(orderedTargets[i]))
             {
                 HoverEnter(interactor, orderedTargets[i]);
                 return;
             }
         }
     }
 }
 void HoverExit(BaseInteractor interactor, BaseInteractable interactable)
 {
     //Debug.LogFormat("Hover Exit: Interactor = {0}; Interactable = {1}", interactor.name, interactable.name);
     interactor.OnHoverExit(interactable);
     interactable.OnHoverExit(interactor);
 }
 /// <summary>
 /// Determines if this interactable can be selected by a given interactor.
 /// </summary>
 /// <param name="interactor">Interactor to check for a valid selection with.</param>
 /// <returns>True if selection is valid this frame, False if not.</returns>
 public virtual bool IsSelectableBy(BaseInteractor interactor)
 {
     return(IsOnValidLayerMask(interactor));
 }
 bool IsOnValidLayerMask(BaseInteractor interactor)
 {
     return((interactionLayerMask & interactor.interactionLayerMask) != 0);
 }