Skip to content

Tutorial: Arranging GameObjects with Layout

Take a set of GameObjects and snap them into a row, a grid, a circle, a fan — anywhere on demand. A Layout Command does it: its Arrange step pulls subjects from one source, slots from another, and 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 Process Component.


How Layout 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 Arrange step — 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["Arrange step<br/>(Layout Command)"]
    R["Subjects snapped<br/>to slots"]
    SS --> LC
    SL --> LC
    LC --> R

The Process Component hosting the command begins on its execution frame (default: on enable) and arranges once. To re-arrange when data changes, begin it again from a Reactor, event or signal, or put the Layout Command straight into that reaction's process.


1. Add a Layout

Create a GameObject named MarkerLayout.

Add Component → Jungle → Spatial → Layout

This adds a Process Component running a Layout Command with one Arrange step. Its fields:

  • Subjects — the subject source.
  • Slots — the slot source.
  • Origin — the object slot strategies anchor their slots to. Defaults to Context, the object the component sits on.
  • Apply Scale — write localScale from each slot (default on), or leave scale untouched.

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 MarkerLayout.


4. Re-Run on Data Changes

Two common patterns:

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). Put a Layout Command with an Arrange step in its process, or a step that begins the MarkerLayout Process Component again.

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

Watch the Arrange step in the Monitor window. It draws the slots the last run used in the Scene view and counts them, and its Layout Now button arranges right away, in edit mode too, with undo.

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


6. Layout vs Layout Strategy

Subtle but useful distinction:

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

The same layout strategy types appear in:

  • A Layout Command's Arrange and Spawn steps.
  • Visualizer entries (inline layout).
  • Octoputs's BatchTransformPipelineManager (batch-friendly variants).

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


7. Vary Slots Along a Shape With Attributes

A shape can carry named values on its points, like point attributes in Houdini. Anything that reads one gets the points around it blended: along a line or curve, the two points on either side; across a surface, every point, the nearest counting most.

  1. Select the shape and open Attributes. Click Add Attribute, name it (for example size) and pick its type: a number, a Vector3 or a color. The default is what the shape reads while it has no points.
  2. Click Add Point, or on a curve Add a Point on Each Curve Point. Set each point's values. Points placed on curve points follow them when you move the curve, and a curve point you add gets its own attribute point with the value blended there.
  3. On the Shape slot source, set Scale By Attribute to size. Each slot's scale is multiplied by the size where it sits, so objects grow and shrink along the shape.

To drive anything else, use the Shape Attribute value in any number or Vector3 field. It reads the attribute where the shape is closest to a position you give it, for example the object's own position.

Attribute points show in the Scene view as pink markers with their values. Drag a free one to slide it along the shape.

Attributes (1, 2 points)
Attribute1sizeFloat×
Default1
Add Attribute
Points
Point 10.1×
size0.5
Point 20.9×
size2
2Add PointAdd a Point on Each Curve Point
A size attribute, small at the start of the shape and large at the end.
SlotsShape
⋯
Slot Scale111
Scale By Attribute3size
The Arrange step's Shape slots read it to scale each slot.
  1. Name the attribute and pick its type.
  2. Add points and set each point's value.
  3. Type the attribute name in Scale By Attribute.

8. 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 re-runs the layout).
  • 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 Layout's own transform).

Next Steps