Forum Discussion

🚨 This forum is archived and read-only. To submit a forum post, please visit our new Developer Forum. 🚨
Anton111111's avatar
Anton111111
Expert Protege
2 years ago

Determine what canvase's element hovered with RayInteractor?

Hi! I need to know what exactly element hovered on canvase. I listen WhenStateChanged of RayInteractor but Interactor in the field Interactable alwase has canvas. And how to understand what button or slider hovered now i don't know.

Also i tried use PointableCanvasModule.WhenSelectableHovered but in this case i can't determine what exact RayInteractor (left or right) hovers.

Can you help me find solution how to determine canvase object and what controller hover it?  

3 Replies

Replies have been turned off for this discussion
  • Jepplen's avatar
    Jepplen
    Expert Protege

    Hi, I have a similar need.
    Did you ever find out how to check which controller (left/right) did the hovering?

  • Jepplen's avatar
    Jepplen
    Expert Protege

    After some digging I did find a solution that worked well enough for my use-case.
    Script goes on UI element you want to check.
    Now, since we are checking "likelyness" it is not 100%, but to be honest I did some fine controller gymnastics and really tried to invoke a faulty response, but it has never failed for me so far. Though I really wish I knew a more explicit way to get this info.

    In addition, you wanted to know which UI element it had hit, well if you attach this script to the UI gameobject that solves that problem as you could check the name of that with just Debug.Log($"Gameobject name is: {name}").

    Though I believe PointerEventData includes that info, don't remember exactly where, but could be:
    eventData.pointerCurrentRaycast.gameObject.name.

     

    public void OnPointerEnter(PointerEventData eventData)
    {
        try
        {
            RayInteractor[] rayInteractors = FindObjectsOfType<RayInteractor>();
            float leftCollisionToPointerDistance = -1;
            float rightCollisionToPointerDistance = -1;
    
            foreach (RayInteractor rayInteractor in rayInteractors)
            {
                Controller controller = rayInteractor.GetComponentInParent<Controller>();
                if (controller != null)
                {
                    if (rayInteractor.CollisionInfo.HasValue)
                    {
                        if (controller.Handedness == Handedness.Left)
                        {
                            leftCollisionToPointerDistance = Vector3.Distance(rayInteractor.CollisionInfo.Value.Point, eventData.pointerCurrentRaycast.worldPosition);
                        }
                        else if (controller.Handedness == Handedness.Right)
                        {
                            rightCollisionToPointerDistance = Vector3.Distance(rayInteractor.CollisionInfo.Value.Point, eventData.pointerCurrentRaycast.worldPosition);
                        }
                    }
                }
            }
           ClosestEventHand(leftCollisionToPointerDistance, rightCollisionToPointerDistance);
        }
        catch (Exception exc)
        {
            Debug.Log($"{exc}");
        }
    }
    
        private void ClosestEventHand(float leftDistance, float rightDistance)
        {
            if (leftDistance > 0 && (rightDistance == -1 || leftDistance < rightDistance))
            {
                Debug.Log("Most likely hand is LEFT");
            } else if (rightDistance > 0 && (leftDistance == -1 || rightDistance < leftDistance))
            {
                Debug.Log("Most likely hand is RIGHT");
            } else
            {
                Debug.Log("Event did not come from controller");
            }
        }