Skip to content

AutoUI Builder

AutoUI is the static entry point for building UI hierarchies in code. It returns a LayoutBuilder that you chain method calls on, then finalise with .Build().

using AutoLayoutPRO.Builder;
AutoUI.Create(parent)
.Column().Padding(16).Gap(8)
.Children(
AutoUI.Create().Text("Hello"),
AutoUI.Create().Text("World")
)
.Build();

Lifecycle

A LayoutBuilder is single-use:

  1. AutoUI.Create() rents a builder from a thread-local pool.
  2. You configure it via chained methods. Add children with .Children(...) / .Child(...) / .Each(...).
  3. .Build() materialises the entire tree, returns the root GameObject, and recycles all builders back to the pool.

After Build(), the builder is invalid. Calling any method on it (or Build() again) throws InvalidOperationException.

The pool is thread-static. The first build allocates; subsequent builds reuse — a 100-node UI is roughly zero builder allocations after warmup.

Entry points

AutoUI.Create()

Most common entry. Returns a fresh LayoutBuilder with no parent — typically nested inside .Children(...).

AutoUI.Create()
.Row()
.Children(
AutoUI.Create().Text("Inner") // nested
);

AutoUI.Create(Transform parent)

Top-level call when you have a parent transform. The built tree is reparented under it.

AutoUI.Create(transform) // 'transform' = MonoBehaviour's transform
.Column()
.Build();

Convenience factories

Shorthand for the most common roots:

MethodEquivalent to
AutoUI.Row()AutoUI.Create().Row()
AutoUI.Column()AutoUI.Create().Column()
AutoUI.Grid()AutoUI.Create().Grid()
AutoUI.GridAutoFit(minColWidth)AutoUI.Create().Grid().GridAutoFit(...)
AutoUI.ScrollView()AutoUI.Create().ScrollViewVertical()
AutoUI.ListView(direction)AutoUI.Create().ListView(direction)
AutoUI.GridView()AutoUI.Create().GridView()
AutoUI.Carousel(direction)AutoUI.Create().Carousel(direction)
AutoUI.Dropdown()AutoUI.Create().Dropdown()
AutoUI.ProgressBar(mode)AutoUI.Create().ProgressBar(mode)

AutoUI.CreateCanvas(name)

Creates a new Canvas + CanvasScaler + GraphicRaycaster (and an EventSystem at runtime if needed). Returns a CanvasBuilder for further config; .UI() returns a LayoutBuilder rooted at the canvas.

AutoUI.CreateCanvas("MainCanvas")
.ReferenceResolution(1920, 1080)
.UI()
.Column().Padding(20)
.Children(...)
.Build();

The chain — what’s available

LayoutBuilder is a partial class with methods grouped into eight files. Find a property in the right area:

TopicWhat’s thereSee
Layout typeRow() / Column() / Grid() / None() / Layout(LayoutType)Sizing
SizingWidth(...) / Height(...) and per-mode shortcuts (WidthFill, WidthHug, WidthPercent, WidthAspect, WidthTextSize); Size, Fill, Hug, TextSize; MinWidth/MaxWidth/MinHeight/MaxHeightSizing
SpacingPadding(...) (1/2/4-arg) / Margin(...) / Gap(...) / GapPercent / PaddingPercent / Wrap() / WrapGap(...)Spacing
DirectionDirection(LayoutDirection) / RTL() / LTR() / ReverseChildren(bool) / Overflow(UIOverflow)RowColumn
AlignmentMainAlign(...) / CrossAlign(...) / MainDistribute(...) / Center() / CrossAxisSelfAlign(...)Alignment
Grid containerGridColumns(int) / GridRows(int) / ColumnGap / RowGap / GridFlow / GridHorizontalAlign / GridVerticalAlign / GridAutoFit(min) / GridAutoFitPercent(pct) / ColumnSizes(string) / RowSizes(string)Grid
Grid itemGridColumn / GridRow / GridColumnSpan / GridRowSpan / GridItemHorizontalAlign / GridItemVerticalAlignGrid
PlacementAbsolute() / Cover() / Ignored() / Order(int) / Visibility(...) / Hidden() / Collapsed() / Left/Right/Top/Bottom/LeftRight/TopBottom(UIPosition) / HorizontalConstraint / VerticalConstraintAbsolute
ChildrenChildren(params) / Children(IEnumerable) / Children(int, Func<int, LayoutBuilder>) / Child(LayoutBuilder) / Child(GameObject) / If(bool, Action) / Each<T>(...)This page
ComponentsText(...) / Background(Color|Sprite) / Icon(Sprite) / RawImage(Texture) / Alpha(float) / AddComponent<T>(...) / OnClick(...) / Button(label, action) / OnPointerEnter/Exit/Down/Up / Draggable / OnBeginDrag / OnEndDragThis page
CaptureCapture(Action<GameObject>) / CaptureLayout(Action<AutoLayout>)This page
Widget buildersScrollViewVertical/Horizontal/ScrollView / ListView / Carousel / Dropdown / ProgressBar / GridView / Inertia / ElasticBoundsper-widget docs
IdentityName(string)
BuildBuild() returns the root GameObjectThis page

Children — composition

There are five ways to add children:

Static list

.Children(a, b, c) // params LayoutBuilder[]; null entries filtered

Single child

.Child(b) // single, no array allocation

IEnumerable

.Children(items.Select(x => Card(x))) // no .ToArray() needed

Indexed factory

.Children(10, i => // build 10 items by index
AutoUI.Create().Text($"Row {i}"))

Each (data-driven, most common)

.Each(items, item =>
AutoUI.Create().Text(item.Name))
.Each(items, (item, i) => // with index
AutoUI.Create().Text($"{i}: {item.Name}"))

Adopt an existing GameObject

.Child(somePrefabInstance) // reparented under this node at Build()

Conditional

.Children(
a,
showAdvanced ? b : null, // null entries are filtered out
c
)
.If(isMobile, b => b.Padding(8)) // apply config conditionally

Capturing references

Need a reference to the built GameObject or component? Two options:

AutoLayout m_Card;
GameObject m_Root;
AutoUI.Create()
.Column()
.Capture(go => m_Root = go) // raw GameObject
.CaptureLayout(layout => m_Card = layout) // typed AutoLayout
.Children(...)
.Build();

Use CaptureLayout for the AutoLayout component (most common); Capture if you need the GameObject for other reasons.

For widget-specific component captures (e.g. the ListView instance), use .Capture on the widget builder:

ListView m_List;
AutoUI.Create().WidthFill().HeightFill()
.ListView(ListViewDirection.Vertical)
.Prefab(rowPrefab, 20)
.ItemCount(items.Count)
.GetItem(i => items[i])
.BindItem(BindRow)
.Capture(lv => m_List = lv)
.End()
.Build();

Components

Common components have one-line shortcuts; anything else uses AddComponent<T>.

.Text("Hello", 24f, Color.white) // TMP, sized by node's TextSize/Hug
.Background(Color.gray) // Image with solid color
.Background(spriteAsset) // Image with sprite
.Background(spriteAsset, Color.white) // sprite + tint
.Icon(spriteAsset) // Image with PreserveAspect
.RawImage(textureAsset) // RawImage (e.g. RenderTexture)
.Alpha(0.5f) // CanvasGroup alpha (auto-added)
.OnClick(() => Debug.Log("clicked")) // Button + click handler (Image auto-added if no Graphic)
.Button("Save", OnSave) // styled button: Padding(12,8) + Center + Background + Text + OnClick
.AddComponent<MyCustomComponent>(c => c.MyField = 42)

Widgets — the End()/Build() pattern

Widget sub-builders (ListView, Carousel, Dropdown, ProgressBar, GridView) follow a consistent pattern:

AutoUI.Create()
.WidthFill().HeightFill()
.ListView(ListViewDirection.Vertical) // returns ListViewBuilder
.Prefab(rowPrefab, 20)
.ItemCount(data.Count)
.GetItem(i => data[i])
.BindItem(...)
.End() // returns to LayoutBuilder
.Build(); // materialise tree

End() adds the widget component to the parent — it does NOT mutate parent sizing/padding. Set Width/Height/Padding on the parent yourself. Build() on the widget builder is a shortcut for End().Build().

Extending the API

Two ways to add your own chainable methods:

Anyone in any assembly can add chainable methods to LayoutBuilder:

namespace MyGame.UI
{
public static class MyAutoUIExtensions
{
public static LayoutBuilder PrimaryButton(this LayoutBuilder b, string label, Action onClick)
{
return b.Padding(12, 8)
.Center()
.Background(new Color(0.18f, 0.36f, 0.96f))
.Text(label, 14f, Color.white)
.OnClick(() => onClick());
}
}
}
// Usage:
AutoUI.Create().PrimaryButton("Save", OnSave).Build();

Partial class

If you’re in the AutoLayoutPRO package itself (or a same-assembly fork), add a new LayoutBuilder.MyStuff.cs file:

namespace AutoLayoutPRO.Builder
{
public partial class LayoutBuilder
{
public LayoutBuilder MyMethod() { /* access private state */; return this; }
}
}

For widget-style builders (your own analogous to CarouselBuilder), follow the existing pattern: a builder class with chainable methods, an End() returning LayoutBuilder, and an entry method on LayoutBuilder (or extension method) to construct it.

Pooling and performance

After warmup, the builder pool eliminates per-build allocations. Things to know:

  • The pool is thread-static. Builds on background threads use a separate pool.
  • A builder cannot escape Build(). If you keep a reference and try to use it later, you’ll get an InvalidOperationException (the same builder may have been re-rented elsewhere).
  • Component-action lambdas (e.g. .OnClick(() => ...)) still allocate closures. For very-hot rebuilds (per-frame UI), prefer setting state on captured references instead of rebuilding.

Common patterns

See GettingStarted for a starting point and Overview for the AutoLayout component reference. Per-widget docs live under Components in the sidebar.