x


More elements inside GUI button

alt text

This is my inventory screen. To display items I use buttons with GUIContent(WeaponName, WeaponIcon). Problem is I need more stuff inside the buttons (texture Icon,string Name, texture Coin Icon,int Price,texture Stone Icon,float Weight). Is it possible to add all of those inside the button, so it's still clickable? Is there any way to tell unity WHERE inside the button to show things mentioned above? Like having the icon on the left side, not centered.

more ▼

asked Aug 13, 2011 at 08:21 PM

4illeen gravatar image

4illeen
123 98 79 82

(comments are locked)
10|3000 characters needed characters left

2 answers: sort oldest

Buttons are far too simple for what you're trying to do. I can't say I'm any expert at GUI, but you probably want to create a GUI Group (see GUI.BeginGroup) and then layout your group as you wish. To make it 'clickable', what I would do is, within the OnGUI() function, do something like:

 Vector2 clickPos = Input.mousePosition;
 clickPos.y = Screen.height - clickPos.y;
 if (Input.GetMouseDown(0)) //user clicked
 {
   foreach(Rect button in myButtons)
   {
     if (button.Contains(clickPos))
       //user clicked on this button, do something
   }
 }


more ▼

answered Aug 13, 2011 at 08:48 PM

Julien.Lynge gravatar image

Julien.Lynge
10.3k 88 92 137

so it's not possible to add more than 1 texture and 1 string inside the button?

Aug 13, 2011 at 08:57 PM 4illeen

Yes, a button is more of a primitive type than an extensible object. You could try doing creative things like painting additional labels over the button and seeing if you're still able to click the button through the labels, but the button object itself can only have 1 texture and 1 string.

Aug 13, 2011 at 09:02 PM Julien.Lynge

GUI.BeginGroup will be your friend if you're doing that. Create a Rect to place your button, then a group using the Rect, then all the other textures and text as a percentage of this Rect, with x,y = 0,0 corresponding to the top left (or just use the layout stuff I linked earlier). That way, you can later resize your button and everything within it will resize as well.

Aug 13, 2011 at 09:26 PM Julien.Lynge

But what is the use of GUI.BeginGroup if simply drawing a label on top of the button does the work?? Could you please add a code snippet with GUI.BeginGroup(), as I have encountered the same problem?

Aug 24, 2012 at 07:28 AM Remo

@Remo: Like you can read on the GUI.BeginGroup page it does two things:

  • Shifts the coordinate-system to the given rect, so elements drawn between BeginGroup and EndGroup are relative to the top left of the group. This way you can just change the position of the group and all containing elements will move along.
  • It clips all elements to the area defined by the rectangle of the group.

Here's a clipping example:

 GUI.BeginGroup(new Rect(100,100,300,200));
 GUI.Button(new Rect(-30,0,60,30), "Button1");
 GUI.Button(new Rect(270,50,60,30), "Button2");
 GUI.EndGroup();

Button1 will start at 70,100 in screen coordinates. Button2 will be at 370,150.

However since the group clips everything that is outside of it's rectangle, Button1 will only be half visible from 100 to 130 instead of 70 to 130

The same for Button2 which is greater than the right border. It's only visible from 370 to 400 (400 is the right border in screen coordinates 100 + 300).

Aug 24, 2012 at 03:05 PM Bunny83
(comments are locked)
10|3000 characters needed characters left

I don't want to encourage people to dig to deep into foreign code, but i guess the UnityEngine.dll is not a big secret since it's all managed code ;). ILSpy gives me this:

 public static bool Button(Rect position, GUIContent content, GUIStyle style)
 {
     GUIUtility.CheckOnGUI();
     int controlID = GUIUtility.GetControlID(GUI.buttonHash, FocusType.Native, position);
     switch (Event.current.GetTypeForControl(controlID))
     {
         case EventType.MouseDown:
         {
             if (position.Contains(Event.current.mousePosition))
             {
                 GUIUtility.hotControl = controlID;
                 Event.current.Use();
             }
             return false;
         }
         case EventType.MouseUp:
         {
             if (GUIUtility.hotControl == controlID)
             {
                 GUIUtility.hotControl = 0;
                 Event.current.Use();
                 return position.Contains(Event.current.mousePosition);
             }
             return false;
         }
         case EventType.MouseDrag:
         {
             if (GUIUtility.hotControl == controlID)
             {
                 Event.current.Use();
             }
             break;
         }
         case EventType.Repaint:
         {
             style.Draw(position, content, controlID);
             break;
         }
     }
     return false;
 }

As you can see the magic behind the GUI.Button function is not black-magic. The whole GUI system is build on top of styles. Styles are almost the only things that can be drawn in the GUI system. A GUIStyle supports only 1 background image, 1 content image and the content-text. More complex GUI-elements like a Scrollview for example uses multiple styles. Each scrollbar uses 4 different styles (background, up-button, down-button, thumb). Those more complex elements just uses other simpler elements internally.

You can build more complex functions on your own. The GUI system is that simple to provide the best extensibility.

You can learn a lot about the GUI system by using ILSpy or any other .NET reflector.

more ▼

answered Aug 13, 2011 at 11:28 PM

Bunny83 gravatar image

Bunny83
78.8k 27 110 344

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x5896
x1369
x26

asked: Aug 13, 2011 at 08:21 PM

Seen: 3113 times

Last Updated: Aug 24, 2012 at 03:17 PM