How do I cause New GUI elements to intercept raycasts?

Disclaimer: This thread may not be in the right place; I’m not sure where it should go. If it’s felt that this needs to be moved to a more appropriate place, please do so.

In my current project I’m prototyping, I’ve hit a snag. You can see for yourself here.

When the match loads up, you are on the Knights side. When you click the castle, you get a command bar for it. When you click the only action button available at present, you’ll notice the WebGL player will freeze entirely, due to a Null Reference exception.

I know exactly why this NullRef is occurring - I have selection code that raycasts to a point that the camera can see; if the cast hits terrain the current selected unit is deselected (set to null). What’s ultimately going on is that you’re issuing a command from a null unit, thus the nullref. However, it’s also a UX bug, because the user may want to spawn multiple units in one go - I can’t just creatively code my way around this and call it ‘done’.

What I used to would do in the old GUI system is put a ‘blocker’ collider behind the GUI which would absorb the raycast, but that’s not an option here becuase the New GUI stuff is all 2D sprite-y stuff. This leads straight into my question…

Question - How do I get the new GUI system to intercept raycasts, such that it doesn’t keep going to the terrain?

Hm, you could add colliders to you UI elements?

What kind of colliders would I use?

2D box or circle colliders depending on the type of UI element? I don’t know, I am basically guessing around. Never tried this, sorry. :slight_smile:

I tried to add a 2D Box Collider to the background GUI element, but that had no effect, possibly because I’m not sure how to even position the collider. I could have sworn the New GUI should be able to be set up to absorb raycasts - Unity isn’t this incompetent, that’s my job. :wink:

Just to be entirely sure of my assumptions, this is my UnitSelectionManager, which is the thing that does the raycast from the camera. Am I using the right stuff? I know the New GUI stuff had an entire new namespace that when I was getting started with it I had to use; it may well be that using the ‘old’ raycasting setup isn’t correct, and I need to do something else. I don’t know. This is really frustrating.

What about using the new Raycasters?

Before running your raycast, you can use your GraphicRaycaster to determine if the point hits a UI element. If it does, then skip the raycast.

I think you’re looking for EventSystemManager.currentSystem.IsPointerOverEventSystemObject()

I’m not at a place where I can run WebGL. I read the OP as arbitrary raycasts. But if it’s just the mouse, IsPointerOverGameObject() is what you want, as StarManta writes.

@TonyLi - I added a check that calls this method…

public bool IsMouseOverUIObject()
{
    bool result = EventSystem.current.currentSelectedGameObject != null;
    DebugMessage("Is the mouse over a UI object?  Answer: " + result);

    return result;
}

…which let the code do what I need it to. One caveat that I intend to go back and look at when I’m polishing this thing - I would really like it if the panels also absorbed raycasts as well. That being said, this is enough to make the GUI serviceable enough to show to people, when I get the other bits of this taken care of.

Here is one I prepared earlier

1 Like