When building a UI with Unity3D’s UGUI system, it’s usually important to make your interface scalable and easy to extend. There are also many cases where the number of items in your UI is dynamic.
The components I’ll cover here are all designed to make layout easier.
LayoutElement
Before we dive into the different layouts, we need to talk about the LayoutElement. Without this component on your UI children, these UI elements aren’t going to do what you want.
The LayoutElement has a couple of options, though you don’t have to use any for layouts to work.
The properties are used in the following manner when a layout controller allocates width or height to a layout element:
- First minimum sizes are allocated.
- If there is sufficient available space, preferred sizes are allocated.
- If there is additional available space, flexible size is allocated.
What this means is when the layout group is laying out your UI, it’s going to first allocate enough space for everything to have it’s minimum sizes.
After all the elements have met their minimum sizes, it’ll try to expand them out to their preferred sizes.. if there’s not enough space, the space is allocated % wise. It’ll calculate out how much space each object wants and assign an equal % of the preferred to each object.
Example: We have two buttons in a group, each with no minimum set.
Button 1 has a preferred height of 100.
Button 2 has a preferred height of 300.
The panel they’re in has a size of 100.
Button one will be scaled to 25 and button two will be scaled to 75.
Example: With Minimum Heights
If the layout elements also have a minimum height, this calculation will be done AFTER the minimum height is assigned.
Button 1 has minimum height of 20, preferred height of 100.
Button 2 has minimum height of 20, preferred height of 300.
Panel size is still 100.
Button one will be 33 and button two will be 67.
Flexible Width & Height
The flexible width and height boxes should probably just be toggles… they accept a numeric value, but that value is always 0 or 1.
When it’s set to 1, the element can expand beyond the preferred setting if the layout controller requests it.
An element set to 0 (or unchecked) will not be used to fill the layout.
LayoutGroups
Now that we’ve covered the LayoutElement, it’s time to look at the different layout group components that can control these elements. There are types available, HorizontalLayoutGroup, VeritcalLayoutGroup, and GridLayoutGroup. The names should give away their layout strategies..
HorizontalLayoutGroup
The Horizontal Layout Group can automatically relocate and resize your UI components on a horizontal plane (left to right). The first child will be on the left and the last child will be on the right.
By default, the layout groups are set to force children to expand and fill in the group’s area. Sometimes that’s the behavior you want, but if you’re using layout elements you may want to un-check those boxes. (or at least the box relevant to the layout type.
For example, on a horizontal layout group, I’ll often uncheck Child Force Expand – Width, and leave Height checked. This will make the elements expand out to get taller, but let me have finer grained control over the width using my layoutelement components.
It’s also important to check Child Controls Size on the width here, so the layout elements actually gain control over their horizontal size (width).
Here you can see the difference. When I check the width box, the children expand out to fill the entire panel. With it unchecked, they’re using the width specified in the LayoutElement components.
Child Alignment
This setting allows you to specify where in the panel the objects will start their layout from. The position you choose depends on your specific UI part, but I tend to default horizontal layout groups to middle left or middle center most of the time.
Padding & Spacing
The padding settings allow you to add a margin between the elements and the edge of the panel the layout group is on. It’s not always needed, but I usually choose a standard padding value for the UI controls. It’s typically between 10-20, but again it totally depends on your layout. My only recommendation is that you choose a value and standardize it as best you can.
Spacing is used between elements. It’s almost always set to something other than 0 in my projects to give a little separation between controls. If you find yourself over-sizing elements in your UI to add a little space.. try switching to using the spacing variable instead.
VerticalLayoutGroup
The vertical layoutgroup is almost exactly the same as the horizontal.. the only difference is the orientation. Because of that, I won’t go into detail as I’d just be repeating myself. Just imagine everything above, with height and width swapped and you’re done 🙂
GridLayoutGroup
Grid Layouts are a bit different. The GridLayoutGroup is used to create a standard grid of rows and columns. It’s a bit like a table in HTML or a grid in many other systems (WPF comes to mind).
Instead of relying on the layout elements to determine size, we specify a cell size on the GridLayoutGroup itself.
In-fact, you don’t need layoutelements at all to use the GridLayoutGroup.
For the grid to work, you need to choose both the X & Y size of the cells (width and height).
Constraint – Flexible
By default, the GridLayoutGroup is set to Flexible. This means the grid will automatically determine the # of rows and columns based on the height and width of the panel.
Example
Your cell size is 100 x 100 and your panel is 300 x 300 wide.
You have 5 children of the grid.
If your Start Axis is Horizontal, you’ll have 3 columns and 2 rows.
If Start Axis is set to Vertical, you’ll have 3 rows and 2 columns.
Constraint – Fixed
You can also choose to specify the column count using the “Fixed Column Count” or “Fixed Row Count” settings for Constraint.
These do what you’d expect and set hard values for the number of columns or rows.
Conclusions
With these layout objects, you can quickly build a UI that’s easy to adjust & automatically fits to your resolution. You can also stack these layout groups inside each other. For example when I build a standard window with a header and body, I’ll start with a VerticalLayoutGroup, then have children under it that have HorizontalLayoutGroups on them. If you’re building an interface with UGUI, spend a little time with these components, get comfortable with them, and your experience will definitely be a lot better.