FlexBox Layout
A frequent case that comes working on UIs is the need to layout content along an axis, for example a menu of buttons in a list. This doesn’t need to be a lot of elements either, often it's useful even with two elements to have them positioned based on each other. The Asset Library contains three Custom Components to help manage this, Horizontal Layout, Vertical Layout, and Layout Element. The Horizontal and Vertical Layout Components work by positioning all the Layout Elements on child Scene Objects into the space allotted to the Layout Component by driving the properties of their ScreenTransform.

These Components will resolve the final sizes of elements using an established algorithm called "FlexBox". This originally comes from CSS but is used across many UI frameworks. This means that outside of these docs there are many resources available on how to use FlexBox layouts in powerful ways.
How to set it up
The Horizontal and Vertical Layout Components have some requirements for their hierarchy:
- The Layout Component should be added to a scene object with Screen Transform
- It should be a child of an Orthographic Camera or Canvas Component (We call this a valid ScreenTransform hierarchy)
- All elements of the layout should be direct children of the SceneObject with the Layout Component and should have a LayoutElement Component.
An example of setting up a Vertical Layout in the inspector. Try the project here

// -----JS CODE-----
//@typename VerticalLayout
//@typename UIButton
//@typename LayoutElement
//@input Component.Camera uiCam
//@input Asset.Material backgroundMat
var DestructionHelper = require('DestructionHelper');
var helper = new DestructionHelper(script);
function createObj(parent) {
var obj = helper.createSceneObject(parent);
obj.layer = script.uiCam.renderLayer;
helper.createComponent(obj, 'Component.ScreenTransform');
return obj;
}
var regionObj = createObj(script.uiCam.getSceneObject());
var region = helper.createComponent(
regionObj,
'Component.ScreenRegionComponent'
);
region.region = ScreenRegionType.SafeRender;
var backgroundObj = createObj(regionObj);
backgroundObj.getComponent('Component.ScreenTransform').anchors = Rect.create(
-0.8,
0.8,
-0.9,
0.9
);
var background = helper.createComponent(backgroundObj, 'Component.Image');
background.mainMaterial = script.backgroundMat;
background.setRenderOrder(-1);
background.stretchMode = StretchMode.Fit;
var extentsTargetObj = createObj(backgroundObj);
background.extentsTarget = extentsTargetObj.getComponent(
'Component.ScreenTransform'
);
var layoutObj = createObj(extentsTargetObj);
var layout = helper.createComponent(layoutObj, script.VerticalLayout);
layout.alignment = 1;
function createSpacer() {
var obj = createObj(layoutObj);
var element = helper.createComponent(obj, script.LayoutElement);
element.requestedSize = new vec2(0, 0);
element.minimumSize = new vec2(0, 0);
element.maximumSize = new vec2(100, 100);
element.growWeight = 1;
}
function createButton(text, onClick) {
var obj = createObj(layoutObj);
var element = helper.createComponent(obj, script.LayoutElement);
//Only requested size matters since grow/shrink weights are 0
element.requestedSize = new vec2(6, 2);
element.growWeight = 0;
element.shrinkWeight = 0;
element.margins = Rect.create(0, 0, 0.1, 0.1);
var button = helper.createComponent(obj, script.UIButton);
button.changeAnimationType('Squish');
button.changeStateValue('normal', 'Color', new vec4(1, 1, 0, 1));
button.changeStateValue('pressed', 'Color', new vec4(0.5, 0.5, 0.2, 1));
button.getTextComponent().text = text;
button.onPress.add(onClick);
return button;
}
createSpacer();
createButton('Option One', function () {
print('Option One clicked');
});
createButton('Option Two', function () {
print('Option Two clicked');
});
createButton('Option Three', function () {
print('Option Three clicked');
});
createSpacer();
This script builds the same menu as the screenshot above. You can try the project here.
Configuring the layout
Horizontal & Vertical Layout
Alignment
Where on the "cross-axis" content should be placed. For example for the Vertical Layout this determines whether content should be placed on the left, center, or right of the available space once their size is resolved

Direction
Which direction on the "main-axis" content should be placed on. For example for the Vertical Layout this is top to bottom or bottom to top

Padding
This allows reserving some space on the interior edge of the layout to stay empty. Content will be laid out into the remaining space.

Grow Weight / Shrink Weight / Margins
The Horizontal and Vertical Layout Components are also Layout Elements, meaning they can be nested as children of other layouts. These properties are to control their behavior in that case and you can find more details in the Layout Element section.
Overrides
The Horizontal and Vertical Layout Components have a series of settings to allow overriding the properties of their child Layout Elements. If you enable one of these overrides, then the value for that property on children will be ignored and instead used from here. For more details on what each property means see the Layout Element section.
Layout Element
Many of the properties of Layout Element are "sizes". These sizes are in world units, meaning for an orthographic Camera this is relative to the “size” property of the Camera and for a Canvas in world space they are in cm.