Skip to content

Tutorial: Arranging GameObjects with LayoutComponent

Take a set of GameObjects and snap them into a row, a grid, a circle, a fan — anywhere on demand. LayoutComponent is the standalone Begin/End-driven component that does it: pulls subjects from one source, slots from another, snaps each subject's transform to its slot.

By the end of this tutorial you'll have a circle of pooled markers that re-arrange themselves whenever the underlying data changes.

Prerequisites: Familiarity with the Process system and ControllableComponent.


How LayoutComponent Works

Three pieces:

  1. A subject source (ILayoutSubjectSource) — what to arrange. Could be a list of GameObjects, a pool's active items, the children of a transform.
  2. A slot source (ILayoutSlotSource) — where to put them. A grid layout strategy, a circle strategy, a list of explicit Transforms.
  3. The Layout's PerformLayout — resolves both, snaps each subject's transform to its matching slot.
flowchart LR
    SS["Subject Source<br/>(what to arrange)"]
    SL["Slot Source<br/>(where to put them)"]
    LC["LayoutComponent<br/>(PerformLayout)"]
    R["Subjects snapped<br/>to slots"]
    SS --> LC
    SL --> LC
    LC --> R

The Layout begins on its execution frame (default: on enable) and runs PerformLayout once. To re-arrange in response to data changes, drive PerformLayout from a Reactor / event / signal — or hook the layout into a Visualizer that calls it after each change.


1. Add the LayoutComponent

Create a GameObject named MarkerLayout. Add the LayoutComponent.

Add Component → Jungle → Data → Layout

Fields:

  • subjects — the subject source.
  • slots — the slot source.
  • origin — a reference transform that slot strategies can use to anchor their slots. Defaults to this component's transform.
  • applyScale — write localScale from each slot (default true), or leave scale untouched.
  • OnLayoutBegin / OnLayoutEnd — UnityEvents fired around each PerformLayout call.

2. Wire the Subject Source

Pick what to arrange. The picker shows the available ILayoutSubjectSource types:

  • From List — explicit list of GameObjects.
  • From Container — pulls items from an IItemContainer<GameObject>.
  • From Pool — every currently-active instance of a PooledObjectCreator.
  • From Children — every immediate child of a Transform.
  • From Detector — every currently-detected GameObject.

For this tutorial pick From Pool and reference your PooledObjectCreator that produces markers.


3. Wire the Slot Source

Pick a layout strategy. Common ones:

Strategy Arrangement
Circular Even spacing around a circle in a plane.
Linear Row or column along an axis.
Grid Rows × columns.
Fan Arc with configurable angle range.
Stack Vertical stack with offset per item.
Explicit A list of Transforms — slot N is transforms[N].

For this tutorial pick Circular:

Field Value
Radius 3
Plane XZ
Start Angle 0
Direction Clockwise

Press Play. The pool's active markers snap to evenly-spaced positions on a 3-unit circle around the LayoutComponent's transform.


4. Re-Run on Data Changes

PerformLayout is public — call it anytime the data changes.

Two common patterns:

Manually from a Reactor

Add a Reactor on the same GameObject. Set its source to whatever drives the data change (the pool's "item added" event, an inventory's change signal). Wire the body to call LayoutComponent.PerformLayout().

Automatically via a Visualizer

Use a Visualizer with a layout strategy directly on its entry. The Visualizer reruns layout automatically after every add/remove/reorder. This is the higher-level pattern when the GameObjects you're arranging are themselves visualized from data.


5. Inspecting Resolved State

After each PerformLayout:

  • ResolvedSubjects — list of GameObjects the Layout placed.
  • ResolvedSlots — list of TransformData slots used.

Useful for debugging mismatches ("I asked for 8 markers but only 6 are showing") and for writing diagnostic gizmos.


6. Layout vs Layout Strategy

Subtle but useful distinction:

  • A layout strategy is a recipe — "circle, radius 3, in XZ". Just data.
  • The LayoutComponent is the runtime host that pulls subjects, resolves slots from the strategy, and writes the result.

The same layout strategy types appear in:

Authoring a new strategy means implementing one interface; it then works in every host.


7. Use Cases

  • Card hand — Fan strategy, every card a subject, the player's hand transform as origin.
  • Marker grid — Grid strategy, every spawn point a subject.
  • Inventory row — Linear strategy, every inventory item a subject (visualized through a Visualizer that calls PerformLayout).
  • Orbiting satellites — Circular strategy, every satellite a subject. Add a Reactor that re-triggers layout on each frame to make them spin (or rotate the LayoutComponent's transform itself).

Next Steps