Clicking over GUI elements fires raycasts...

Upgraded to 2.5.1 and I’m still getting raycasts firing off even when the mouse is down over a gui button.

If you want to test it, create a plane 200x200 and align the main camera to view it. put these scripts on an EmptyGameObject and run. I angled the camera so there was some plane visible for a hit and some “sky” visible for a no-hit. Also, the “100” button was OVER the plane so it could register a hit if clicked through.

When I click on the 100 button, I get a mix of “100” and “Hit Something” printed on the console. Sometimes I click without getting “Hit Something” but mostly it registers the button hit and the collider hit.

Adding Event.current.Use() to the button click makes no difference. I’m temporarily averting this by adding a full screen button that captures “raycast clicks” and tells the raycast to fire but I’d like to know if this is a bug or working as intended. If it’s a bug, I’ll bug report it.

Anyone from UT have any input?

Thanks,

Jason

code below:

raycast.js

function Update () {

if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, 1000)) {
print ("Hit something");
}
else
print ("Hit Nothing");
}

}

button.js

function OnGUI ()
{
   GUI.depth = 100;
   if (GUI.Button  (Rect(400,400,100,100),"100"))
   {
   Event.current.Use();
   print("100"); 
	}

}

Okay, so.

The “invisible button covering the screen to catch “real” clicks” doesn’t work. Unfortunately while GUI.Buttons click through, they do absorb OnMouseOver (and enter, exit,down, up), so with the full screen button in place, I could no longer select objects on the playing field (which also relied on OnMouseOver.

What I did eventually do and it works:

is to remove the full screen button.

add a boolean into the OnMouseEnter and OnMousExit behaviors of my “GroundPlane” which is the target of the raycast clicks for object movement purposes. Setting this boolean to true when over (on enter) and false when not (on exit).

reference this boolean in my object raycast script. If it is true, then proceed with the raycast, otherwise, a GUI element consumed the mouseover and do no raycasting.

I also use the same functions to check right mouse button click and raycasting on certain objects. I just had these objects’ OnMouseEnter and Exit set the boolean for doing raycast, same as the GroundPlane.

Again, if someone from UT could comment on this, it would be appreciated. I just want to know if this is “Working as Intended” or truly a bug I should report.

code :

groundplane.js

static var raycastClick : boolean = false;

function OnMouseEnter()
{
 raycastClick = true; // if over plane set true
}
function OnMouseExit()
{
 raycastClick = false; // if not set false
}

selectableobject.js (same on enemy or player)

var moving : boolean = false;

function Update()
{
 if (moving) // set by selecting object from OnMouseOver event
  DoMovement();
}

function OnMouseEnter()
{
 if(enemy) // set me as a raycast target if I am an enemy
  {
   groundplane.raycastClick = true;
  }
}

function OnMouseExit()
{
 if(enemy) // remove me as a raycast target if no longer over me
  {
   groundplane.raycastClick = false;
  }
} 

function OnMouseOver()
{
 if(Input.GetMouseButtonDown(0)  !enemy) // select me if over me and I am clicked on, also start me moving
  {
   // do selection stuff
  moving = true;
  }

}

function DoMovement() //  move me to the raycast target if a position on the ground plane is clicked on
{
 if (Input.GetMouseButtonDown(0)  groundplane.raycastClick)
  {
    // do raycast  movement stuff
  }
}

Jason

From what I understand this is currently a limitation of the GUI system. If would be nice if the Unity folks exposed the state of every GUI element. This way we could catch all input events.

I might as well post this here, too:

Here’s one of the silliest workarounds I’ve done so far:

Make a plane and place it right in front of your main camera where your gui element is. Turn off the mesh renderer and there ya go. The raycast will hit the plane, you won’t see it cause it’s invisible.

The only problem with this is that the size of my gui elements changes with different screen proportions, and the plane doesn’t change in the same way.

Note that the plane needs to be right on top of the camera so that none of your scene elements gets in front of it (and then becomes clickable)

Any improvements with the problem of proportions will lick this sucker.