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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How do I cause New GUI elements to intercept raycasts?

Discussion in 'Scripting' started by AndrewGrayGames, Oct 4, 2015.

  1. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,822
    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?
     
  2. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    Hm, you could add colliders to you UI elements?
     
  3. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,822
    What kind of colliders would I use?
     
  4. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    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. :)
     
  5. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,822
    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. ;)

    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.
     
    Last edited: Oct 4, 2015
  6. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,533
    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.
     
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    I think you're looking for EventSystemManager.currentSystem.IsPointerOverEventSystemObject()
     
  8. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,533
    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.
     
  9. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,822
    @TonyLi - I added a check that calls this method...

    Code (csharp):
    1. public bool IsMouseOverUIObject()
    2. {
    3.     bool result = EventSystem.current.currentSelectedGameObject != null;
    4.     DebugMessage("Is the mouse over a UI object?  Answer: " + result);
    5.  
    6.     return result;
    7. }
    ...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.
     
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Here is one I prepared earlier

     
    AndrewGrayGames likes this.