Avoiding GUI Elements on click when using Camera.main.ScreenPointToRay

Specs:
Unity version: 2018 2.5f1 personal

Scenario:
My player is controlled by clicks on the screen in Update on a script added to the player:

if(EventSystem.current.IsPointerOverGameObject()){
Ray   ray  = Camera.main.ScreenPointToRay(Input.mousePosition);
float dist = 0;
new Plane(-Vector3.forward, transform.position.z).Raycast(ray, out dist);
body.AddForce( (ray.GetPoint(dist) - transform.position) * 100f );
}

Next, I have a GUI Button setup on my Canvas with a listener in a script added to the GUI Button element:

m_BombButton.onClick.AddListener(ClickBomb);
void ClickBomb()
{
        Debug.Log("m_BombButton pressed...");    
}

Desired Goal:
My goal is to prevent the ScreenPointToRay from going through the GUI Button and acting as a click on the screen.

Things I've tried:
- Many different implementations of EventSystem.current.IsPointerOverGameObject()
- OnPointerDown/Up with IPointerDown/UpHandler ( could get this to fire, but stopped working)
- Using click on Sprite Images as wells as GUI Button. Neither seem to fire.
- Legacy (pre 4.6) solutions

Not sure if these functionalities work differently on 2018 than previous versions? But this is becoming a two week search with no solid results. Docs are better, but still do not describe anything beyond the basics. Google just keeps bringing me back to the same links.

I found 1 solution... though, I feel it is very unorthodox and too intensive to pass as a viable solution. But so does adding a script to every single gameobject in a scene just so you don't click on them... ridiculous.

So here:
https://discussions.unity.com/t/693565
Which then led me to:
https://answers.unity.com/questions/1429689/specific-ui-element.html
So thanks to Hellium for the code snippet

private bool IsOverUI(){
    bool isOverTaggedElement = false;
        if (EventSystem.current.IsPointerOverGameObject() )
        {
            PointerEventData pointerData = new PointerEventData(EventSystem.current)
            {
                pointerId = -1,
            };

            pointerData.position = Input.mousePosition;

            List<RaycastResult> results = new List<RaycastResult>();
            EventSystem.current.RaycastAll(pointerData, results);

            if (results.Count > 0)
            {
                for( int i = 0 ; i < results.Count ; ++i )
                {
                    if( results[i].gameObject.CompareTag( "Button" ) )
                        isOverTaggedElement = true ;
                }
            }
        }
        return isOverTaggedElement;
     }
}

Unity... do better... this is bs

1 Like

Great answer! Thanks a lot!

Don't forget to add Physics Raycaster to the camera!