uLayout is simple UI layout system designed as a drop-in replacement for Unity's VerticalLayoutGroup and HorizontalLayoutGroup, implementing a core subset of the flexbox spec from CSS. The system operates purely on RectTransforms, meaning full compatibility with native uGUI components like Image, RectMask2D, etc.
It's designed with performance in mind—LayoutRoot only triggers an update when resize events occur, and only the Layout objects which had a child resize are updated. The demo scene costs ~3.5ms on my machine (i9-9900k), most of which is canvas updates.
uLayout can be installed from the Unity Package Manager via git URL: https://github.com/pokeblokdude/uLayout.git
Alternatively, you can import directly into your project with a .unitypackage file, available in the Releases tab.
uLayout requires there to be a LayoutRoot component at the top of the UI hierarchy. "Top" in this case is relative—as long as it's above every Layout object, you're good to go! There's also nothing stopping you from using multiple LayoutRoot objects in the same scene.
uLayout components can be quickly added to your scene via GameObject > UI > Layout (or scene-view right-click menu).
Functionality is split into two parts: sizing and positioning. These are calculated in separate passes, where sizing executes bottom-up on the hierarchy, while positioning runs top-down (there's actually a secret third pass for emulating flex-grow behavior but that's not super important to know).
All layout elements can choose one of three SizingMode options for each axis:
FitContent: fits the rect tightly around its contents, taking into account padding and internal spacing
Fixed: rect size is not controlled by uLayout (uses the pre-defined RectTransform size)
Grow: rect grows to fill its parent container (if parent is Layout, uses padding & distributes grow child size along primary axis)
If your object isn't a container, you can use the LayoutItem component, which only implements the sizing half of the logic. For full flexbox child layout features, use the Layout component, which inherits from LayoutItem, but adds the rest of the features.
Any LayoutItem can be exluded from the layout (use absolute positioning, as they say in CSS), with the "Ignore Layout" toggle.
Further explanation and examples can be found in the sample scene at Examples/LayoutDemo.unity. If you've never used CSS flexbox before, I also recommend taking a look at this guide that covers the basics with super helpful illustrations :)
uLayout also supports TextMeshPro TMP_Text objects, using the LayoutText component. This also derives from LayoutItem, offering the same sizing options. This allows text objects to resize depending on contents and font size.
Resizing text is relatively expensive, and triggers a lot of canvas updates—I would generally avoid having a ton of animated LayoutText objects running at once, and you also might want to consider spreading them across different canvases.
- Ignore Layout (
bool): whether to exclude this element from layout positioning - Size Mode: Sets the rect sizing mode for each axis. "FitContent" has no effect (use derived classes below)
- x (
SizingMode) - y (
SizingMode)
- x (
- Padding: Set a buffer width between each edge and the layout contents
- top, bottom, left, right (
float)
- top, bottom, left, right (
- Direction (
enum)Row: Position children left-to-rightColumn: Position children top-to-bottomRowReverse: Position children right-to-leftColumnReverse: Position children bottom-to-top
- Justify Content (
enum)Start: Align children to the start of the primary axis (depends onDirection: left for Row, top for Column, etc)Center: Align children to the center of the primary axisEnd: Align children to the end of the primary axisSpaceBetween: Space children evenly across the primary axis
- Align Content (
enum)Start: Align children to the start of the cross axis (depends onDirection: top for Row, left for Column, etc)Center: Align children to the center of the cross axisEnd: Align children to the end of the cross axis
- Inner Spacing (
float): Sets the gap between children on the primary layout axis. Does not work withJustification.SpaceBetween(layout will be wrong, just set to 0)
- Max Font Size (
float): The maximum size the text will grow when theTMP_Text's "Auto Size" option is enabled (when disabled, this option has no effect). Only works with "Fixed" or "Grow" sizing modes.
- Console reports missing references on import - simply enter Play Mode once and it should fix itself (also you need the TextMeshPro assets)
- No
overflowoptions
Contributions are welcome and greatly appreciated! Open a pull request and I'll do my best to review it in a timely manner. For contributors: Please do not go through and alter existing code style and/or syntax. This makes it needlessly difficult to parse your changes, and I will simply end up changing it back anyway!
