Blocking interaction with 3D game objects by UI game objects

56 views Asked by At

I have some 3D objects, if I click on them then something happens. I implemented this using Physics ray casting like this

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
               // Do something
            }

Now I have some UI panels (screenoverlay) which has buttons, if any clickable 3D object is under the panel and I click on a button or on the UI panel, the 3D model also receives the click. . I don't want that. I want the UI to block interaction with any 3D objects it overlays.

Currently I am achieving this by checking if cursor is over a ui or not whith this,

        if (Input.GetMouseButtonDown(0) && CanClickOnObject && !UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
        {

            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {

This does the work done but I am not sure if this is the best way to do so. Is there any proper or better way?

2

There are 2 answers

7
Zbajnek On

If you have a raycast that triggers on mouse click it will always trigger no matter where you click or what you have opened (UI included).

So you need to prevent the raycast with some condition and in your case, I don't think there's a better way to do that.

0
derHugo On

Define

proper or better way

EventSystem.IsPointerOverGameObject returns true for any GameObject that is reacting to the EventSystem.

Depending on your setup this might include 3D objects that are implementing any of the EventSystem interfaces - most commonly the IPointerXYHandler interfaces - using a PhysicsRaycaster on the Camera. So this might include more objects than pure UI elements.

In that case you might not come around to additionally execute a UI raycast (EventSystem.RaycastAll) and check for a specific UI layer.

As long as that is not the case for your project the way you are using might be good enough