How do I make raycast hit with a canvas element(screen space overlay)

10,536

You can't use a Physics.Raycast for UI elements nor 2D colliders.

In general what you want to hit is rather a specific Graphic component such as an Image or Text component with RaycastTarget enabled.


If you want to hit a BoxCollider2D you'll have to use the Physics2D.Raycast instead. However this is not used to raycast in the Z direction but only works for hitting the collider from the side via an XY direction.


For actually hitting UI you have to use a different type of Raycast not going through Physics but using an EventSystem.RaycastAll like e.g.

var pointerEventData = new pointerEventData{ position = touchPos};
var raycastResults = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerEventData, raycastResults);

if(raycastResults.Count > 0)
{
    foreach(var result in RaycastResults)
    {
        ...
    }
}

Note further that you have a check for tag ChallangeUI but your UI object has layer UI.

Share:
10,536
Levin
Author by

Levin

Updated on June 24, 2022

Comments

  • Levin
    Levin almost 2 years

    For some reason, my 2D Overlay is not reacting to the raycast hit while the 3D objects work fine. I've searched the internet for quite some time now and I still can't find a solution to it. (I'm kinda new-ish to both C# and Unity so my knowledge is limited)

    If anyone can shed some light on this issue I have, it will be greatly appreciated!

    The issue here is that I would want my cursor to display a console message when I click on the 2D Overlay. The 3D Objects work and displayed the relevant message in the console but for some reason, the 2D graphic isn't detecting the raycast hit.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.XR.ARFoundation;
    
    public class rayCast_Test : MonoBehaviour
    {
        [SerializeField]
        public GameObject TutorialUI;
    
        public Canvas gameChara2D;
        [SerializeField]
        private float rayCastDistance = 25f;
        [SerializeField]
        float DistanceFromCamera = 1f;
    
        private ARRaycastManager aRRaycastManager;
        private Vector3 touchPos;
        private Vector3 touchOrigin;
    
    
    
        private bool onTouchHold = false;
    
        private RaycastHit hitObject;
    
    
    
        private void Awake()
        {
            aRRaycastManager = FindObjectOfType<ARRaycastManager>();
        }
    
        // Update is called once per frame
        void Update()
        {
    
    
            if (Input.GetMouseButton(0))
            {
                touchPos = Input.mousePosition;
    
                if (!onTouchHold)
                {
                    Ray ray = Camera.main.ScreenPointToRay(touchPos);
    
    
                    if (Physics.Raycast(ray, out hitObject, rayCastDistance))
                    {
                        if(hitObject.transform.CompareTag("Moveable"))
                        {
                            onTouchHold = true;
                            touchOrigin = Input.mousePosition;
                            Debug.Log("Hello. This is a 3D object");
                        }
                    }
    
                    if(Physics.Raycast(ray, out hitObject, rayCastDistance))
                    {
                        if (hitObject.transform.CompareTag("ChallengeUI"))
                        {
                            Debug.Log("Hello. This is a 2D object");
                        }
    
                    }
                }
    
            }
    
            if(Input.GetMouseButtonUp(0))
            {
                onTouchHold = false;
            }
    
    
        }
    }
    

    Scene Tree Canvas Properties