Author Topic: Ignore objects under UI  (Read 15799 times)

capitalj

  • Jr. Member
  • **
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 88
    • View Profile
Ignore objects under UI
« on: July 14, 2012, 10:59:47 PM »
Hi, this is probably something simple, but I couldn't find an answer to it from searching the forums. Is there a simple way to ignore input to objects underneath the UI? for example, if I have a character that is underneath a UI button and the button is pressed, can I have it so that the character is not selected as well? I've done this before by setting bool flags but that doesn't seem like the proper way to do this reliably. I've read a bit about using raycasts to ignore, is that the right direction?

-JJ

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Ignore objects under UI
« Reply #1 on: July 14, 2012, 11:14:17 PM »
The character won't be selected. The button will intercept the event. Are you doing your own raycasts? Make sure not to. Use NGUI's event system. It already does all the raycasting for you (and handles intercepting events as a bonus).

capitalj

  • Jr. Member
  • **
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 88
    • View Profile
Re: Ignore objects under UI
« Reply #2 on: July 15, 2012, 12:43:56 PM »
Well, I'm using a touchmanager system that does raycasting for colliders for general touch interaction with in-game objects. Here's how it does it:

  1.  if (TouchManager.GetTouchPos (id, out pos)) {
  2.             Ray ray = Camera.mainCamera.ScreenPointToRay (pos);
  3.             RaycastHit hit;
  4.             if (collider.Raycast (ray, out hit, distance)) {
  5.                 if (hit.collider == collider) {
  6.                     worldPos = hit.point;
  7.                     touchedCollider = true;
  8.                 }
  9.             }
  10.         }

Or are you saying I should use NGUI's colliders for my other objects?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Ignore objects under UI
« Reply #3 on: July 15, 2012, 01:26:28 PM »
There is no such thing as "NGUI colliders".

NGUI events are sent to any and all colliders, provided the event mask matches. NGUI already does raycasting for you and handles all mouse and touch events. You don't need to do it yourself.

Get rid of your touch manager system. It's unnecessary.

capitalj

  • Jr. Member
  • **
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 88
    • View Profile
Re: Ignore objects under UI
« Reply #4 on: July 15, 2012, 04:54:41 PM »
I tried adding the UIEventListener to an object in the game that has a collider on it:
  1. UIEventListener.Get(BackgroundObject).onClick += BackgroundClick;

But it doesn't respond. Of course it is an object that is not in the NGUI camera hierarchy and is not on the same layer as the rest of the UI (although I tried changing the layer to match but it doesn't do anything). Do I have to add a UI button script to every object that I want to get the events on?


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Ignore objects under UI
« Reply #5 on: July 15, 2012, 05:54:08 PM »
You need the UICamera script attached to the camera that sees this object. That's what sends out the events.

Dad

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 1
    • View Profile
Re: Ignore objects under UI
« Reply #6 on: July 16, 2012, 04:24:31 PM »
There is no such thing as "NGUI colliders".

NGUI events are sent to any and all colliders, provided the event mask matches. NGUI already does raycasting for you and handles all mouse and touch events. You don't need to do it yourself.

Get rid of your touch manager system. It's unnecessary.

This is not an ideal situation in our case - there are things our touch handling does that isn't covered in NGUI's.  Ideally we'd like to be able to make a call like GUILayer.HitTest ( http://docs.unity3d.com/Documentation/ScriptReference/GUILayer.HitTest.html?from=GUIElement ) to decide if NGUI will be handling the touch or if we should.  Does something like this exist?  If not I don't see how we can use NGUI in our project. 

Appreciate clarification on this by anyone who knows.  Thanks.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Ignore objects under UI
« Reply #7 on: July 16, 2012, 05:06:35 PM »
UICamera.hoveredObject tells you what the mouse is hovering over.
UICamera.lastHit has the results of the last raycast hit (available during NGUI callbacks).

JRoch

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 140
    • View Profile
Re: Ignore objects under UI
« Reply #8 on: July 16, 2012, 05:41:40 PM »
I think I explained my solution to this in another thread, but I'll reiterate it here.  I wanted to make sure I didn't respond to scrollwheel events while over NGUI elements that weren't meant to respond in some way to a scroll event.  So for the main client area, minimap, and three-quarter view windows I wanted the handle mouse scroll, but for hovering over any other panel or widget I wanted scroll to be ignored.

So I wrote a class (script) that I attached to every "parent" NGUI panel that makes up the UI of my app.  This class uses public static variable storage of a Hashtable to keep track of all gameobjects that are part of a given NGUI panel hierarchy.  On start each panel with the script attached adds itself and all of its children to the Hashtable.  The key is this.gameobject.transform.instanceID.  The value is the original parent's gameobject.transform.instanceID.  I also use this Hashtable to be able to instantly check if a given NGUI item (gameobject) is a child of a given panel, which I used to code behaviors where a panel will auto-hide if it loses mouse hover focus.

Anyhow, with this attached to all UI items it is then very easy to have an ability to check whether or not to react to mouse events.  You can create handler logic that continually stores a boolean of whether or not one of your tracked NGUI panels is being hovered.  So in your non-UI code for the main interface you can do a simple check in the OnGUI (or similar) events that deal with mouse input and check if an NGUI panel is currently being hovered.  If it is, just return out of the mouse handler without responding to the event.

You likely don't even need the Hashtable structure if you aren't trying to implement other behaviors.  Just have a class that you attach to ALL your objects that have NGUI colliders that stores the "selected" value of the OnSelect() event to a public static boolean.  Any time OnSelect is processed it updates that variable, which means it should properly follow the state of whether or not you're hovering a UI element or not.

reptilebeats

  • Guest
Re: Ignore objects under UI
« Reply #9 on: July 16, 2012, 05:53:58 PM »
if i read this right could you not just simple use 1 << 8, to change what layer the hit responds to, and just change this, works for me.

JRoch

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 140
    • View Profile
Re: Ignore objects under UI
« Reply #10 on: July 16, 2012, 08:03:39 PM »
if i read this right could you not just simple use 1 << 8, to change what layer the hit responds to, and just change this, works for me.

I read that like four times and have no idea what you're referring to.  I mean, there's the word "layer" in there, which makes me think the rest of the words around it should make sense...

capitalj

  • Jr. Member
  • **
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 88
    • View Profile
Re: Ignore objects under UI
« Reply #11 on: July 17, 2012, 12:28:55 AM »
JRoch, he's referring to a layermask that lets you restrict which layers will register a hit:

http://docs.unity3d.com/Documentation/ScriptReference/LayerMask.html

-JJ

JRoch

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 140
    • View Profile
Re: Ignore objects under UI
« Reply #12 on: July 17, 2012, 01:11:43 PM »
Ah.  I've been avoiding getting to granular with layers and depending upon them for anything beyond the basics because it seems like Unity sometimes forgets itself and resets and entire branch of the tree back to Default layer.  Anyhow, I was more confused by the "1 << 8" ( one shift left eight bits?) and the other pieces of the sentence having ambiguous references.  When he says, "just change this" I'm not sure what "this" refers to.

JRoch

  • Full Member
  • ***
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 140
    • View Profile
Re: Ignore objects under UI
« Reply #13 on: July 17, 2012, 04:03:22 PM »
Oh, I just checked, and I have this at the top of my scene's OnGUI() handling:

  1.         if (UICamera.hoveredObject != null)
  2.         {
  3.             // don't handle events via OnGUI while hovering NGUI items
  4.             return;
  5.         }
  6.