Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to hide GUI buttons?

Discussion in 'Immediate Mode GUI (IMGUI)' started by Hakimo, Jul 15, 2010.

  1. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi,

    I'm using GUI.toggle to show a menu. Is there a way to hide the small toggle radio button when the menu is showing?

    Thanks :)

    -Hakimo
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    You can use the toggle's state variable to hide it when it is not needed:-
    Code (csharp):
    1. var showingMenu: boolean;
    2.  
    3. function OnGUI() {
    4.    if (!showingMenu) {
    5.       showingMenu = GUI.Toggle(toggleRect, showingMenu, "Show Menu");
    6.    } else {
    7.       // Menu code.
    8.    }
    9. }
    The menu code should include something that can set showingMenu to false again when the menu session is over. Since the toggle is not visible when it is set, you might consider using a simple button control to show the menu.
     
  3. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Thanks very much. I always seem to forget that I can use the if(!condition).

    At the moment, I'm still trying out to see what's the best way to create a pause menu. So far I've looked at designing it thought GUI.skin and now I'm looking at GUI.Texture :)

    Cheers.

    -Hakimo
     
  4. Ezzerland

    Ezzerland

    Joined:
    Jul 1, 2010
    Posts:
    405
    I'd recommend GUI.Skin, or at the least, GUI.Style

    If you need any further help regarding this, don't hesitate to ask. But the documentation for unity regarding this is pretty good.
     
  5. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi,
    I thought so too. I think the reason I'm using GUI.texture is because I can use my own textures as buttons since my menus are very simple. With GUI.skins, I think it's better for stuff like forms and complex stuff. Also, skinning the GUI.skins to match what I want seems a bit complicated.

    Thanks again.
    -Hakimo
     
  6. Ezzerland

    Ezzerland

    Joined:
    Jul 1, 2010
    Posts:
    405
    If you are skinning more than one type of GUI object, for example, a GUI.Box and a GUI.Button, or more, then you are better off using GUI.Skin

    I would be more than happy to provide examples of how to do this.


    On the otherhand, if you are only customizing one item in the scene, for example a GUI.Button (or multiple buttons that will all look the same), then I would recommend GUI.Style

    Again, I would be willing to give you code snippets on how to do this, but I strongly recommend one or the other of these two. They are very easy to implement, and very flexible :)

    To each their own, but I'm here if ya need :)
     
  7. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Wow thanks for the reply. After what you said, it seems GUI.Skin is what I need. If I'm not using GUI.textures, I do want to customise the box and the buttons.

    Just a head's up, I'm learning Unity through a book called Unity Game Development Essentials. Given the example screenshot it showed, it suggest to use GUI.textures.

    What I'm going for is something like this:



    Except that each button will have a different texture and colour. If I were to use GUI.Skin, I plan to use GUI.toggle. Is that possible to skin as well?

    Thanks again.
    -Hakimo
     
  8. Ezzerland

    Ezzerland

    Joined:
    Jul 1, 2010
    Posts:
    405
    For the above example, I would use a GUI.Skin

    You can add custom fields inside of this GUI.Skin for each different button, and name it as you please. This would be done inside of the unity inspector, and therefore reduce the amount of changes etc made in your scripts, as unity would take care of the bulk of coding for you.
     
  9. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi Ezzerland,
    I'm using GUI.Skin at the moment. I'm not sure if it's the right way.

    Here's the code I wrote:

    Code (csharp):
    1.  
    2. // Skin
    3. var mainmenuSkin : GUISkin;
    4.  
    5. // GUI Area Width
    6. var areaWidth : float;
    7.  
    8. // GUI Area Height
    9. var areaHeight : float;
    10.  
    11. function OnGUI()
    12. {
    13.     GUI.skin = mainmenuSkin;
    14.    
    15.     var ScreenX = ((Screen.width * 0.5) - (areaWidth * 0.5));
    16.     var ScreenY = ((Screen.height) - (areaHeight * 0.5));  
    17.     GUI.Box (Rect (20,50,280,380), "", "menuBG");
    18.     GUILayout.BeginArea(Rect(ScreenX, ScreenY, areaWidth, areaHeight));
    19.    
    20.         if(GUILayout.Button("","buttonPlay"))
    21.         {
    22.             print("Play");
    23.         }
    24.        
    25.         if(GUILayout.Button("","buttonBg"))
    26.         {
    27.             print("Background");
    28.         }
    29.        
    30.         if(GUILayout.Button("", "buttonHow"))
    31.         {
    32.             print("How to");
    33.         }
    34.        
    35.         if(GUILayout.Button("", "buttonMusic"))
    36.         {
    37.             print("Music");
    38.         }
    39.        
    40.         if(GUILayout.Button("", "buttonCredits"))
    41.         {
    42.             print("Credits");
    43.         }
    44.        
    45.     GUILayout.EndArea();
    46. }
    47.  
    It does display a menu that I wanted but in code, I felt that putting the "GUI.Box" outside of the GUILayoutBeginArea seems wrong. In the inspector, I set the Area Width and Area Height as 150 and 720 respectively. The reason is so that my buttons stay at the middle.

    Also, now that I have the menu, how do I assign the functions of the buttons? E.g For the How To, I want to display an image text. Basically hide the other buttons > show the image and include a back button. Do I have to open a level to a new scene or? Not sure how to approach this.

    Oh yea, I have some active button I'm using. How do I set it so when a button is pressed, it'll stay in that state? e.g. Music is on or off?

    Thanks

    -Hakimo
     
  10. Ezzerland

    Ezzerland

    Joined:
    Jul 1, 2010
    Posts:
    405
    The GUI.Box outside of the layout menu is fine, the problem with that is that you specified two different co-ordinance for where your box shows and where your menu shows.

    Try:
    Code (csharp):
    1. GUI.Box (Rect (ScreenX-0, ScreenY-0, 280, 380), "", "menuBG");
    You will have to subtract from ScreenX and ScreenY to get the box to center around the menu, if that was your goal with the box, or you could manually do the layout how you want. I put the -0 part in so that you were aware you could do it that way as well. Wasn't sure if you knew :)


    Your >> print("Background"); <<
    is exactly how you assign functions to the buttons. print is a function that you're using in a manner that if (button is pushed) print (button name).

    If you want to write your own function, then outside the OnGUI (Further down in your script), you would write your own. It would look something like this:

    Code (csharp):
    1. var musicIsPlaying = true; //music is on by default
    2.  
    3.  
    4. function OnGUI() {
    5.  
    6.  if(GUILayout.Button("", "musicSwitch")){
    7.          MyMusicOnOffFunction();
    8.          print("Music On/Off Button");
    9.  }
    10.  
    11. }
    12.  
    13. function MyMusicOnOffFunction() {
    14.  
    15.   //function code here
    16.   if (musicIsPlaying) {
    17.     //music is currently playing and we want it off
    18.     musicIsPlaying = false;
    19.   } else if (!musicIsPlaying) {
    20.     //music is currently off and we want it back on
    21.     musicIsPlaying = true;
    22.   }
    23.  
    24. }
    Then all you need to do is add the if statement around the bit of code that plays your music, so that it only executes if your musicIsPlaying Boolean variable is set to true.

    This same above code should answer your img on/off question as well. You set a Boolean variable to false by default, so that img or w/e does not show until that var is set to true.

    You can do this without the work of the extra function as well, like so:

    Code (csharp):
    1. if(GUILayout.Button("", "musicSwitch")){
    2.          if (musicIsPlaying) {
    3.              //music is currently playing and we want it off
    4.              musicIsPlaying = false;
    5.          } else if (!musicIsPlaying) {
    6.              //music is currently off and we want it back on
    7.              musicIsPlaying = true;
    8.          }
    9.          print("Music On/Off Button");
    10. }

    But, one last thing to add.
    If the only function of some of your buttons is to set one var to true/false, I recommend using a toggle switch instead. This can easily be made to look like a button, or again you could use your GUI.Skin to make it look as whatever you wish.

    Hope this helps :)

    Thanks,
    Rob
     
  11. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi Ezzerland,

    Thanks again for the help. Lol I never tried adding the (ScreenX - 0). I had to manually put in a different value so the menus will position itself the position I want. If I use Screen X and Y as its parameters, the areaWidth and areaHeight will have conflict with the position of the buttons as well. I tried to edit the margin-top for the buttons, but they won't budge :p

    As for the buttons, e.g. Music, I have one texture each for on and off state. How do I make it so when the button is switched off, it'll show and remain as switched off? I place the "off texture" in the "active" part in custom style. It shows the texture when click but it doesn't stay there. Tried to put it in "On-active" as well but that didn't work :(

    I have some more questions, but I'll take it one step at a time.

    Thanks.

    -Hakim
     
  12. Ezzerland

    Ezzerland

    Joined:
    Jul 1, 2010
    Posts:
    405
    Gonna make a slight alteration to one of my above examples. In your GUI.Skin you named each button with its own skin, from what I can tell. You'll make use of GUIStyleState and then just alter the GUIStyle within the GUI.Skin through code to get you the end result.

    Code (csharp):
    1. var musicIsPlaying = true; //music is on by default
    2. var musicOnSkin : GUIStyleState; //button should say turn off
    3. var musicOffSkin : GUIStyleState; //button should say turn on
    4.  
    5.  
    6. function OnGUI() {
    7.  
    8.  
    9.  if(GUILayout.Button("", "buttonMusic")){
    10.          MyMusicOnOffFunction();
    11.          print("Music On/Off Button");
    12.  }
    13.  
    14. }
    15.  
    16. function MyMusicOnOffFunction() {
    17.  
    18.   //function code here
    19.   if (musicIsPlaying) {
    20.     //music is currently playing and we want it off
    21.     buttonMusic.normal = musicOffSkin;
    22.     musicIsPlaying = false;
    23.   } else if (!musicIsPlaying) {
    24.     //music is currently off and we want it back on
    25.     buttonMusic.normal = musicOnSkin;
    26.     musicIsPlaying = true;
    27.   }
    28.  
    29. }
    ofc I left out the GUI.Skin in the example, but you get the idea :)
    If you have a hover effect, you can change it the same way.
     
  13. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi Ezzerland,

    Sorry I had to finish some other parts but now I'm back at fixing the GUI. I'm stuck at the moment using GUIStyleState. I tried using the:

    Code (csharp):
    1.  
    2.  GUI.skin.buttonMusic.normal = musicOffSkin;
    3.  
    Now, I'm getting errors on that the "buttonmusic" is not a member of the GUISkin. Also, what did you mean by alter the GUI.Style within the GUISkin? Also, I made the buttons using Custom Styles, did you mean I must add another element for the image or?

    Thanks again.

    -Hakimo
     
  14. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Sorry to bump this thread again but does anyone know how to change a GUI button after it being pressed? Basically I have a switch on music button with it's image and once pressed, I like it to change to a switch off button.

    Ezzerland recommended me using GUIStyleState but I have no idea how to use it or to make mine work

    Hope someone can help with this.

    Thanks in advance.
    -Hakimo
     
  15. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    If you don't want to use Styles you could always use a simple bool.

    if (button is active){
    make button with your "active" image
    } else {
    make button in the exact same spot with the same size and your "inactive" image
    }
     
  16. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi KyleStaves,

    I did use a boolean that is basically the toggle class in GUI. I set up my code as:

    Code (csharp):
    1.  
    2.  var musicSwitch : boolean = false;
    3.  
    4.  function OnGUI() {
    5.  ....
    6.  musicSwitch = GUILayout.Toggle(musicSwitch, "", "button");
    7.  
    8.  if(musicSwitch)
    9.  {
    10.   myMusicFunction();
    11.  }
    12. }
    13.  
    14. function myMusicFunction() {
    15.  if (musicPlayer.isPlaying)
    16.       {
    17.         musicPlayer.Stop();
    18.       }
    19.      
    20.      else if(!musicPlayer.isPlaying)
    21.       musicPlayer.Play();
    22. }
    23.  
    So right now, it does work visually, but it's not functioning properly. It's a bit hard to describe but one I switch off > close menu > open menu > switch on, it doesn't play the music. I have to close the menu again, click the switch button and exit menu for it to play :p

    Not really sure how to swap buttons properly and making sure the function works.

    * I just noticed that the swap button image is fine but I think there's something wrong with my function logic.

    Thanks again.
    -Hakimo
     
  17. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Whoops, I managed to fix it now :) Thanks again for the replies :)
     
  18. darthevil

    darthevil

    Joined:
    Sep 6, 2010
    Posts:
    13
    Hi I know that it was a while back and the subject has changed a bit now but back on the second post I want to do the same thing but I'm new to scripting and I didn't really understand the code. Could someone please explain it in an easier way thanks.
     
  19. Hakimo

    Hakimo

    Joined:
    Apr 29, 2010
    Posts:
    316
    Hi DarthEvil,

    Welcome to the Forum. Before doing this, I suggest you read up about GUISkin and a bit of scripting. That's what I used to create this. Here's the code you referring to:

    Code (csharp):
    1.  
    2. function OnGUI() {
    3.    if (!showingMenu) {
    4.       showingMenu = GUI.Toggle(toggleRect, showingMenu, "Show Menu");
    5.    } else {
    6.       // Menu code.
    7.    }
    8.  
    Not sure which part you're not familiar with but I'll try:

    The "showingmenu" is actually just a button image I made in GUISkin. What the code does is "if the button is not showing, then show the button. When you click on it, it will show the menu(Menu Code) and will hide the button" This is a special feature of GUI.Toggle. The menu code basically contains GUILayout.Buttons. I do recommend reading the links I mentioned before for better understanding.

    Hope it helps.
    -Hakimo
     
  20. darthevil

    darthevil

    Joined:
    Sep 6, 2010
    Posts:
    13
    Thanks for clearing that up and for the links, I'm gonna look at them now.