IsPointOverGameObject() not working as intended!!!

Like many others I tried also to block/prevent Physics.Raycast from going through UI elements (canvas) using “EventSystem.current.IsPointerOverGameObject()” but unfortunately without success…

Im not sure why, but the “EventSystem.current.IsPointerOverGameObject()” is reacting to all UI gameobjects (what I´m looking for), but also to any gameobject on my scene that have an active collider attached to it. In other words it returns true for UI and non-UI gamebojects!!

For the Physics.Raycast part, Im using a simple function that Im calling inside Update() :

   protected void HandleInput()
   {
    Ray ray = RayCam.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    float _rayDistance = Mathf.Infinity;
    LayerMask _rayMask = ( 1 << this.UnitsLayer | 1 << this.GroundLayer);
    
    if (Physics.Raycast(ray, out hit, _rayDistance, _rayMask))
    {
      // *** Ray hit a Unit
      if (hit.collider.gameObject.layer == this.UnitsLayer){// do something}
      // *** Ray hit the Ground
      if (hit.collider.gameObject.layer == this.GroundLayer){// do something else}
    }
   }

Isn´t “IsPointerOverGameObject()” supposed to return true only if the EventSystem object is an UI element??

Notice : adding more conditions check like “EventSystem.current.currentSelectedGameObject.layer == 5” didn´t solve the problem neither because the “EventSystem.current.currentSelectedGameObject” is always returning NULL.

Caching the EventSystem (the one created inside the Canvas) into a variable “myEventSystem” and going through the same process didn´t change anything, too.

What am I doing wrong? Any suggestions to solve this problem?

Many thanks in advance.

EventSystem.current.IsPointerOverGameObject() will return true for non-ui gameobjects if there is a PhysicsRayCaster attached to one of your gameobjects.

Either remove the PhysicsRayCaster or modify PhysicsRayCaster.EventMask, in my case i had to switch off TransparentFX.

In my case IsPointerOverGameObject returns TRUE if(touch.phase == TouchPhase.Began),
BUT it returns FALSE if(touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)

So you can remember if you started your touch over UI and cancel it at the end.