• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
7
Question by jahroy · Apr 22, 2011 at 12:41 AM · guiguilayer

How to draw GUI controls on top of each other

My game has a dropdown menu that I've implemented with a GUI.Toggle and a GUI.SelectionGrid. The toggle button determines whether or not the selection grid should be displayed.

The SelectionGrid appears over another (unrelated) group of GUI.Toggle buttons. Even though the toggle buttons are drawn first, they still steal the mouse focus when the mouse is over the selection grid.

Both components are drawn in the same OnGUI function. Actually, they're both drawn in the same function, which gets called from the OnGUI function in my script.

Here is a screenshot that demonstrates the problem:

alt text

The mouse is over the 'Foo' item in the selection grid, yet the toggle button enters its hover state and will become active if I click my mouse.

Here's the code that draws the selection grid, which is called AFTER the list of toggle buttons has been drawn:

var buttonRectangle = getDropdownButtonRect(); var choicesRectangle = getScrollBoxRect(buttonRectangle);

showMenuChoices = GUI.Toggle(buttonRectangle, showMenuChoices, buttonLabel, "dropdownButton");

if ( showMenuChoices ) {

 lastSelection = chosenMenuOffset;

 GUI.Label(choicesRectangle, dropdownBackground);
 chosenMenuOffset = GUI.SelectionGrid(choicesRectangle, chosenMenuOffset, menuNameList, 1, "dropdownMenu");

 if ( chosenMenuOffset != lastSelection ) { 
     resetButtons();
     showMenuChoices = false;
 }

 if ( isCloseDropdownClick() ) {
     showMenuChoices = false;
 }

}

Thanks in advance for any help...

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

6 Replies

· Add your reply
  • Sort: 
avatar image
8
Best Answer

Answer by jahroy · Apr 23, 2011 at 09:06 AM

I finally figured this out now that I've accepted the fact that you must draw GUI elements that overlap in separate scripts.

Once I realized that, there were a couple other things I needed to figure out:

  • Both scripts must declare a class with a name that matches the file name (even javascript)
  • The classes must extend MonoBehaviour
  • Both scripts need to declare their GUI.depth in their OnGUI function
  • GUI.depth is an integer
  • The script with the lowest depth will be drawn last and will capture the mouse input

filename: DrawMeFirst.js

class DrawMeFirst extends MonoBehaviour { var bottomLayerNumber : int = 10;

 function OnGUI ()
 {
     GUI.depth = bottomLayerNumber;
     drawStuffUnderneathOtherStuff();
 }

 function drawStuffUnderneathOtherStuff ()
 {
     if ( GUI.Button(Rect(0, 0, 100, 100), "I am underneath") ) {
         Debug.Log("This will never get printed");
     }
 }

filename: DrawMeLast.js

class DrawMeLast extends MonoBehaviour { var topLayerGetsMouseInput : int = 1;

 function OnGUI ()
 {
     GUI.depth = topLayerGetsMouseInput;
     drawControlsYouCanClick();
 }

 function drawControlsYouCanClick ()
 {
     if ( GUI.Button(Rect(0, 0, 100, 100), "I am on top") ) {
         Debug.Log("I will always get clicked");
     }
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
3

Answer by JoeStrout · Jul 13, 2011 at 04:26 PM

You don't actually have to separate your different layers into separate scripts. The real problem is just a bug in GUI.Button; it doesn't properly honor GUIUtility.hotControl.

See more details, and a replacement button function, on this Unity Forum thread.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jahroy · Jul 17, 2011 at 05:37 AM 0
Share

Sweet. That's great because my separate script for one GUI element feels pretty silly and hacky. Can't wait to try this out!

avatar image Gru · Nov 02, 2015 at 04:57 PM 0
Share

I believe this is inaccurate, GUI.depth refers to complete OnGUI of a script. Setting it multiple times inside the same OnGUI would lose the effect.

avatar image JPLKit · Dec 03, 2015 at 03:36 PM 0
Share

This helped me diagnose a bug where I had two buttons overlapping each other on the screen and I couldn't manage to trigger one of the buttons no matter what its depth or order in the OnGui function.
(One of the buttons should have been a box as a background image, but I made it a button for debugging purposes and never changed it.)

avatar image
1

Answer by Sindorej · Dec 15, 2013 at 04:27 PM

Simple

GUI.depth = 1;

//draw your front gui here

GUI.depth = 2;

//draw your back gui here

Of course you can add even more layers.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by ruben_hiet · May 11, 2011 at 12:25 PM

i tried this but it won't work where do you have to set your buttons or toggle's? do i have to set them in a function callt drawControlsYouCanClick or just under it? i tried everything can you make a simple sample with 2 buttons 1 greater then the other on top of each other?

i gave my scripts the right name and tried and tried but it won't happen. its always clicking the wrong one :(

thanks in advance,

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jahroy · May 12, 2011 at 04:25 AM 0
Share

drawControlsYouCanClick() is just a fake (descriptive) name that I used for my example. In my example GUI elements that are drawn by the function 'drawControlsYouCanClick' will be drawn on top of GUI elements that are drawn by the function 'drawStuffUnderneathOtherStuff'. I'll change my example code to make it more demonstrative...

avatar image jahroy · May 12, 2011 at 04:36 AM 0
Share

If you post your code I'd be happy to look at it...

avatar image ruben_hiet · May 12, 2011 at 02:44 PM 0
Share

well if I use your code (your forget the brackets of your class) I can't see any buttons. So I placed them out of the class but now it doesn't work because both buttons are hoverd. So what am I doing wrong...? Why can't I see the buttons when they are in the class?

thanks for helping me out :)

avatar image jahroy · May 12, 2011 at 04:19 PM 0
Share

$$anonymous$$ake sure that you're dragging your classes onto a GameObject that is actually enabled and part of your scene. Other than that it's pretty hard to tell if I can't see your code.

avatar image ruben_hiet · May 12, 2011 at 06:38 PM 0
Share

i used the code above with that same buttons for a simple try out. i always do that before i set it into my real project so with that code above it has to work right?

I attached the scripts to a box in my scene and my camera has a GUI Layer so thats not the problem. I can see GUI elements but not the ones in the classes. Did you test your code or? can you test it for me? would be very helpfull i can't get it to work and I really do need those elements on top. Thanks

Show more comments
avatar image
0

Answer by hudi · Jan 26, 2014 at 10:40 PM

It seems this is appropriate topic so I'll leave it here. GUI.Button is not broken - but if you do something like this in your script "useGUILayout = false;" it may seems so.

I just spent 5 hours debugging this problem that appeared from "nowhere". Imagine two buttons written in 2 scripts overlapping each other.

 Script1
  button1
 
 Script2
  button2

To set which one will be on top of the other you only need to set execution order in the inspector. Let's say the execution order is first Script1 then Script2. Now if you click on the button1 which is in foreground the button1 will execute.

Here comes the nasty "useGUILayout = false". If you wrote that line of code, say in Script 1, the rendering order would be the same but instead of executing button1 you will end up executing button2!

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image semiessessi · Feb 13, 2014 at 01:42 PM 0
Share

"only need to set execution order in the inspector"

this is a thing you can do? where? not obvious... but i'd find it enormously useful

avatar image hudi · Feb 13, 2014 at 08:35 PM 0
Share

Just click on a script in Unity and above the script preview you will see an icon that says "Execution order". And btw. it seems that if you instantiate a prefab with some script the execution order will have no effect. So it only works with scripts attached to objects that were created manually. I hope you get it. :)

avatar image JorobusLab · Jan 28, 2015 at 10:48 PM 0
Share

You're the saviour...of my time xD. "useGUILayout = false", think that is messing me up, gonna try erasing that line of code, I bet is that, thanks!

avatar image hudi · Nov 03, 2015 at 08:50 AM 0
Share

JorobusLab, I strongly recommend you not to use old unity GUI system because it is pure crap. I switched to GUI that I created with an orto camera, quads with colliders... - much much better, faster, reliable.

You will feel a lot of pain if you continue to use that disaster of a GUI. ;)

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

9 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to make the tab key to show/hide GUIlayer 1 Answer

help with errors 2 Answers

GUI is not showing up, but script seems to be fine 1 Answer

GUILayer hit doesn't work. Any help? 0 Answers

Drawing a GUI onto a 3D object 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges