How do I make a solid GUI?

How do I make it so raycasting doesnt go through my GUI? I have a script that places objects on a mouseclick but I dont want it to place said object when I click a button on my GUI.

How is your GUI implemented? Are you using the built-in GUI system?

I am scripting the GUI

Yes but how?

GUITexture + GUIText, OnGUI (-> built-in system), GUIX, EZGUI, something else

built in system

So you use OnGUI? (both first things I mentioned there are the built-in system. GUITexture + GUIText are Unity 1.x gui, OnGUI is Unity 2.x gui)

OnGUI

Unless I’m mistaken, you’ll just have to handle this yourself (I don’t think the GUI system ‘intercepts’ click events in the way you’re describing).

One solution you could try would be set a flag when a click event is ‘used’ in OnGUI(), and then check the flag in the relevant Update() function to see if the click event has already been used. (After this check, you would then clear the flag.)

Set a blocked flag when your button is clicked… isnt ongui called before update?

That’s basically what I said above.

According to this at least, it looks like it’s called after Update().

I don’t think this works, Update() will still catch the click. What about doing all your click testing in OnGUI()? *yes, uggh. Otherwise you have to do bounds testing with Rect.Contains() or something similar.

Assuming JoeSSU had the same thing in mind that I did, nobody’s saying that you can keep the click from being registered in the Update() function. Rather, the idea is to set a flag indicating that the click was ‘used’ in the previous update cycle’s calls to OnGUI(). In other words, it’s simply a program logic issue (we’re not talking about altering the way Unity handles events).

I should mention though that I haven’t actually tried the proposed solution myself, so it’s at least somewhat speculative.

Jesse, yeah, I understand what you are saying, but I have yet to get that to work. Reason being that Update() may catch a click before OnGUI() gets it. So OnGUI has not had a chance to set your custom bool that tells Update() to ignore the event.

I’d love to be proven wrong though!

Yeah, that’s a tough one. Perhaps a better solution would be to ‘mask off’ the areas of the screen occupied by the GUI using simple bounding rectangle containment tests. It wouldn’t be a terribly convenient solution (in that you’d have to keep the ‘masks’ in sync with the GUI controls), but it seems like it would be fairly foolproof.

The simplest way to do this is have your last button be an invisible one that covers the whole screen. So if no other button is clicked, it gets clicked, and you can either do a raycast at that point or convert MousePosition to world space.

Expanding on what’s been said above, you should create a variable for holding all of your GUI Rects (var myRects : Rect[ ] or something) and then use Rect.Contains(Input.mousePosition) for each one to determine whether or not you should use the mouse click to shoot a raycast. You can do that in the Update loop, which will make things pretty simple.