Author Topic: How to use NGUI´s Raycasts to avoid using custom raycasts  (Read 1252 times)


  • Newbie
  • *
  • Thank You
  • -Given: 5
  • -Receive: 0
  • Posts: 29
    • View Profile
How to use NGUI´s Raycasts to avoid using custom raycasts
« on: March 12, 2015, 02:20:15 PM »
Hello Forum,

i came up with this issue while having problems detecting if my mouse is on an UI-Element or in the 3D World. The mistake was, that i had a custom raycast-function going to detect what object in the 3D world the mouse is touching and ngui also does this, for his UI Elements. So i read a lot about it in this Forum and in the documentation and found the advise to use NGUI´s raycast, instead of custom ones, but up to this point i´m not getting how to achieve this.

What i think i got right (pls correct me if something is wrong):

- Having an UICamera on any ingame Camera means NGUI-Raycasts against the set layermaks.
- If those raycasts hit something, colliders or rigidbodys, you get access to the NGUI-Events like OnClick, OnHover etc in those gameobjects.
- If nothing on the set layermask is hit, you can forward the eventsystem to a custom eventhandler on any gameobject using UICamera.fallThrough = this.gameObject; You then have access to these Events in this GO.

For serperating UI-hits from 3D World hits, ArenMook suggested in an other thread the following setup (if i got this right, pls also correct):
- UI-Camera has for sure UICamera-Script, Event-Type set to 2D/3D UI, EventMask set to UI only
- Main-Camera has also UICamera-Script, Event-Type set to 3D-World, EventMask set to nothing

Is it possible that this setup is outdated, cause the current version gives a fallThrough in any case and the UICamera is not needed on the Main Camera anymore? The thread is from 2012:

Assuming that i got it more or less right up to this point i´m trying to use those fallThrough Events for detecting which gameObject in the 3D world was hit, without using additional raycasting. I have the UICamera-Script only on my UI-Camera , set to UI-only, rest of the hits fall through my EventHandler, though i also tried the setup with UICamera on MainCamera but it seems to make no diffrence.

My problems:

I need information what 3D-world, non UI GameObject was hit by the fallThrough event, like i would check it wth a raycast. All functions i tried so far didn´t provide this information or did i missed something?

- OnHover-Event seems to only trigger, when the fallThrough gets triggered, means when i switch from UI to non UI Element. It seems not to trigger constantly when i´m hovering over any 3DWorld colliders.

- UICamera.lastHit doesn´t give me the current hit Object
  1. public void OnClick()
  2.     {
  3.         Vector3 obj = UICamera.lastHit.transform.position;
  4.         Debug.Log(obj);
  5.     }              

It seems to refere to the 2D UI-Layer, cause all positions i get are like (a, b, 0)

I also have started a workaround using the fallThrough system only to check if we are on UI or not and then do some custom raycasting to check what i´m hitting in the 3DWorld, but if i got all the other informations right, this is not the way things should be done here.

thx in advance


  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,154
  • Toronto, Canada
    • View Profile
Re: How to use NGUI´s Raycasts to avoid using custom raycasts
« Reply #1 on: March 12, 2015, 08:36:23 PM »
UICamera.fallThrough can be set to something, but it's often better to go for specific delegates instead -- UICamera.onClick for example. It depends on what you're trying to do.

For example in Windward I have UICamera on both the UI camera and the Main Camera. Main camera's UICamera script has a mask set not to none, but to actual layers I want hit -- ships, and such. This makes it possible to hover over a ship and receive a OnHover notification on it, which I then use to display its name and health information. I also use OnClick to make it possible to right-click on those ships. Note that this is the easiest setup, and fallThrough isn't used at all.

For more complex interaction I use delegates such as UICamera.onHover. When I start an operation that involves dragging a target reticle around (such as AoE skill or building placement) I assign a UICamera.onHover delegate that will do a raycast into the terrain / water and reposition a 3D reticle accordingly.

This way I don't worry about having terrain and water be clickable most of the time. Custom raycasts performed while trying to use a skill or place a building take care of it only when necessary.