Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Detecting if a UI object is blocking a 3d object

Discussion in 'Physics' started by ziv_unity718, Jul 26, 2022.

  1. ziv_unity718

    ziv_unity718

    Joined:
    Apr 25, 2022
    Posts:
    4
    Hey everyone!
    I'm trying to write code that detects whether I see a 3d object or not. I combined various methods, like getComponent<Renderer>().isVisible and raycasting against the bounding points of the collider, but nothing seems to detect whether there's a UI object that's blocking (appearing in front of) it.
    Physics.Raycast doesn't detect UI objects.
    I can't run raycast with GraphicsRaycaster since I have a lot of UI objects in the scene and it'll be too inefficient.
    I'm also using WebGL.

    Anyone has any ideas on how to detect if a UI element is blocking a 3d object?
     
  2. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    Not sure about checking if it's entirely blocked, but you could use WorldToViewportPoint to get its position on the screen, and check if a UI element is over that spot. It would only check for the exact position of the object though, and wouldn't account for an object's size.
     
  3. ziv_unity718

    ziv_unity718

    Joined:
    Apr 25, 2022
    Posts:
    4
    Thanks a lot for the answer @RadRedPanda!
    Can you point me to how to calculate if a UI object is over this viewport point? I can't use raycasting from that point since it doesn't detect UI objects :(
     
  4. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    You can convert your UI element to a Rect object, and then check if the Rect has the point inside of it using Rect.Contains(). You would need to use WorldToScreenPoint instead though, so I incorrectly mentioned that in my last post.
     
  5. ziv_unity718

    ziv_unity718

    Joined:
    Apr 25, 2022
    Posts:
    4
    This would not necessarily work for UI objects that are in world space (instead of screen overlay), since their Rect might not contain the point, but still block the 3d object from view :\
     
  6. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    I didn't know you were rendering in World Space. Doesn't this mean that you have many different Canvases though? From reading the documentation, it would seem that the GraphicsRaycaster only casts on the Canvas object it is attached to, so would not necessarily be inefficient in colliding with too many stray UI objects.
     
  7. ziv_unity718

    ziv_unity718

    Joined:
    Apr 25, 2022
    Posts:
    4
    I render in both World Space and Screen Overlay
    Yea but that would mean I have to use the Graphics Raycaster for each canvas (basically call Raycast for every UI canvas I have, which is a lot)
    The canvases are also dynamic, which means I'll have to track at every frame how many canvases exist (some are destroyed, some are created)
     
  8. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,596
    I don't know how realistic this is for your project, but you could just create one Canvas for all of the UI elements you want to be, and just set the positions of all of your UI elements within that Canvas space. I also suspect you're using World Space to do something similar to rendering UI above a parent object, and to get around that, you could update the position of the UI element in code to follow the object. This would probably be in the same place you update the UI elements to look at the camera.