Skip to content
Control Flow Nodes

Control Flow Nodes

Bool Split

Splits a bool into two complementary float gates. True output = 1 when Condition is true; False output = 1 when Condition is false. Use to drive two downstream float ports from a single bool without a second Branch node.

Inputs

  • Condition (Bool)

Outputs

  • True (Float)
  • False (Float)

Tips

  • True and False outputs always sum to 1: wire both to separate multiply nodes to gate complementary effects.
  • Equivalent to two Branch nodes (condition, 1, 0) and (condition, 0, 1) in a single node.

Branch

Routes True Value or False Value to Result based on Condition. Both inputs are always evaluated: this is a data-flow select, not a jump.

Inputs

  • Condition (Bool)
  • True Value (Float)
  • False Value (Float)

Outputs

  • Result (Float)

Branch (Geometry)

Routes one of two Geometry inputs to the output based on Condition. The not-taken arm’s geometry, scatter, and collider work is skipped entirely (except SubGraph nodes 910/911/912 which always run).

Inputs

  • Condition (Bool)
  • True Geometry (Geometry)
  • False Geometry (Geometry)

Outputs

  • Geometry (Geometry)

Branch (Polygon)

Routes one of two Polygon inputs to the output based on Condition. The unused side is skipped when it doesn’t feed anything else. Note: polygon nodes marked editor-preview-only still run on both sides while you are previewing in the graph window, whichever side is taken: the skip saves work in the finished tool, not in the preview.

Inputs

  • Condition (Bool)
  • True Polygon (Polygon)
  • False Polygon (Polygon)

Outputs

  • Polygon (Polygon)

Branch (Spawn)

Routes one of two Spawn inputs to the output based on Condition. The unused side’s collider work is skipped when it doesn’t feed anything else, but a Scatter Output inside either side always runs (not yet lazy).

Inputs

  • Condition (Bool)
  • True Spawn (Scatter)
  • False Spawn (Scatter)

Outputs

  • Spawn (Scatter)

Branch (Spline)

Routes one of two Spline inputs to the output based on Condition. The unused side is skipped when it doesn’t feed anything else.

Inputs

  • Condition (Bool)
  • True Spline (Spline)
  • False Spline (Spline)

Outputs

  • Spline (Spline)

Branch (Vector3)

Routes one of two Vector3 inputs to the output based on Condition. Both inputs are always evaluated.

Inputs

  • Condition (Bool)
  • True Value (Vector3)
  • False Value (Vector3)

Outputs

  • Result (Vector3)

ForEach Pair

Runs the loop body once per segment (consecutive point pair) of a spline. Exposes Index, Seed, Center, Rotation, Length, Start, and End for each segment: wire Start/End into Geometry/Transform to place geometry at each segment’s endpoints.

Inputs

  • Spline (Spline)
  • Seed Geometry (Geometry)

Outputs

  • Geometry (Geometry)
  • Index (Float)
  • Seed (Float)
  • Center (Vector3)
  • Rotation (Vector3)
  • Length (Float)
  • Start (Vector3)
  • End (Vector3)

Tips

  • This node walks between points, not at them: use For Each Spawn Point for ‘place a thing at each point’. For Each Spline Segment answers ‘build a thing between each pair of points’ (railings, fences, beams, panels).
  • Fence Wall slices a pre-made mesh asset along a spline; this node builds each segment procedurally with Index and Seed in scope: use it when every segment is generated, not stamped.
  • Seed Geometry is optional: leave unwired to start each iteration with an empty geometry accumulator.
  • To skip an iteration: put a Branch (Geometry) in the loop body with the False arm unwired. The skipped iteration’s work (geometry, scatter, colliders) is not evaluated.
  • To break early: wire the same stop condition into both Loop End’s Stop When and a Branch (Geometry) gate that wraps the body.

ForEach Polygon Corner

Runs the loop body once per corner of a single polygon. Exposes index, seed, X, and Y for each corner.

Inputs

  • Polygon (Polygon)
  • Seed Geometry (Geometry)

Outputs

  • Geometry (Geometry)
  • Index (Float)
  • Seed (Float)
  • X (Float)
  • Y (Float)

Tips

  • Polygon points are in the polygon’s 2D plane (X = world X, Y = world Z for footprint polygons). Wire X and Y into geometry placed in that plane.
  • Wire the Seed output into Random nodes inside the body for per-corner variation that stays deterministic.
  • Seed Geometry is optional: leave unwired to start each iteration with an empty geometry accumulator.
  • To skip an iteration: put a Branch (Geometry) in the loop body with the False arm unwired. The skipped iteration’s work (geometry, scatter, colliders) is not evaluated.
  • To break early: wire the same stop condition into both Loop End’s Stop When and a Branch (Geometry) gate that wraps the body.

ForEach Polygon Island

Runs the loop body once per polygon in a shape group, publishing that polygon: its solid contour plus any holes: on the Polygon output.

Inputs

  • Polygon (Polygon)
  • Seed Geometry (Geometry)

Outputs

  • Geometry (Geometry)
  • Island Index (Float)
  • Seed (Float)
  • Polygon (Polygon)

Options

  • maxOutputPoints: Maximum float2 points in the published per-island polygon, counting NaN separators between the solid contour and its holes. Default 256. Raise if WarnPolyCapacityTruncated fires (too many points in one island). Does not affect the contour-count cap: if WarnIslandContourCapExceeded fires instead, reduce the number of separate shapes or split the group upstream.

Limitations

  • A hole is not a shape. Holes are grouped with the solid contour that contains them, so a courtyard building is one iteration, not two. A shape sitting inside a hole is depth 2 and is its own iteration.
  • When a published shape exceeds Max Output Points (default 256) it is truncated and WarnPolyCapacityTruncated fires: raise the knob to fit the largest shape in the group.
  • Groups with more than 1,024 separate contours are truncated at that cap and WarnIslandContourCapExceeded fires: the remedy is fewer separate shapes (fewer Voronoi seeds or scatter points) or splitting the group upstream. Raising Max Output Points does not help.

Tips

  • Wire the Polygon output: not the original polygon: into the body. Wiring the source polygon back into the body gives every iteration the whole group.
  • Winding is normalised on the published shape (solid counter-clockwise, holes clockwise), so Extrude and Revolve read it correctly whatever the source group’s winding was.
  • Wire the Seed output into Random nodes inside the body for per-shape variation that stays deterministic.
  • To skip an iteration: put a Branch (Geometry) in the loop body with the False arm unwired. The skipped iteration’s work (geometry, scatter, colliders) is not evaluated.
  • To break early: wire the same stop condition into both Loop End’s Stop When and a Branch (Geometry) gate that wraps the body.

ForEach Polygon Pair

Runs the loop body once per side of a polygon (consecutive corner pairs, wrapping to close). Exposes Index, Seed, Center, Angle, Length, Start, End, and Rotation for each side.

Inputs

  • Polygon (Polygon)
  • Seed Geometry (Geometry)

Outputs

  • Geometry (Geometry)
  • Index (Float)
  • Seed (Float)
  • Center X (Float)
  • Center Y (Float)
  • Angle (Float)
  • Length (Float)
  • Start X (Float)
  • Start Y (Float)
  • End X (Float)
  • End Y (Float)
  • Rotation X (Float)
  • Rotation Y (Float)
  • Rotation Z (Float)

Tips

  • A polygon with N vertices has N edges: the last edge connects vertex N−1 back to vertex 0.
  • Wire Rotation X/Y/Z into a GeometryTransform’s Rotation to orient geometry on the edge. It sends the unit’s local +Z to the edge’s outward normal and keeps local +Y up, so a panel authored facing +Z lands flat on the wall facing out.
  • Rotation puts local +Z on the outward normal, which on a counter-clockwise polygon forces local +X anti-parallel to the direction of travel: in Unity’s left-handed frame the two cannot both point forward. Triangle winding and mesh handedness are unaffected; only the left-right arrangement of asymmetric panel detail mirrors relative to travel around the ring.
  • Angle is a math-plane angle (CCW from +X toward +Z): not a Unity Y-Euler, which runs the opposite sense. Plugging Angle directly into a Y rotation reflects the frame rather than rotating onto the edge. Use Rotation instead; Angle is for measuring, not orienting.
  • Wire Start/End X and Y into procedural geometry: place a wall panel, fence post, or edge strip per edge.
  • Seed Geometry is optional: leave unwired to start each iteration with an empty geometry accumulator.
  • To skip an iteration: put a Branch (Geometry) in the loop body with the False arm unwired. The skipped iteration’s work (geometry, scatter, colliders) is not evaluated.
  • To break early: wire the same stop condition into both Loop End’s Stop When and a Branch (Geometry) gate that wraps the body.

ForEach Spawn

Runs the loop body once per spawn point in a scatter list. Exposes index, seed, world position, rotation, scale, and variant index for each point.

Inputs

  • Spawn (Scatter)
  • Seed Geometry (Geometry)

Outputs

  • Geometry (Geometry)
  • Index (Float)
  • Seed (Float)
  • Position (Vector3)
  • Rotation (Vector3)
  • Scale (Float)
  • Variant (Float)

Tips

  • Index is the upstream emit order; from Geometry to Points, spawns arrive vertex-by-vertex face-by-face (Box default order: Front, Back, Right, Left, Bottom, Top).
  • Rotation outputs Euler degrees (ZXY). Surface Scatter and Curve Scatter produce normals/tangents; Grid, Poisson, and Volume scatter produce identity rotation (0,0,0).
  • Seed Geometry is optional: leave unwired to start each iteration with an empty geometry accumulator.
  • Position carries the frame the upstream scatter produced: wire it straight into a collider Center port when scatter is over geometry.
  • To skip an iteration: put a Branch (Geometry) in the loop body with the False arm unwired. The skipped iteration’s work (geometry, scatter, colliders) is not evaluated.
  • To break early: wire the same stop condition into both Loop End’s Stop When and a Branch (Geometry) gate that wraps the body.

Loop Begin

Starts a geometry-accumulator loop. Pair with Loop End. Seed Geometry is optional: leave unwired to start with an empty accumulator.

Inputs

  • Count (Int)
  • Seed Geometry (Geometry)
  • carrySeeds (Float)

Outputs

  • Geometry (Geometry)
  • Index (Float)
  • carryOuts (Float)

Options

  • carryChannels: Named carry channels threaded through loop iterations. Each channel has a name and float type; add channels via the Carry section to pass a running cursor, cumulative height, or flag from one iteration to the next.
  • stopAtIteration: Debug scrubber: 0 runs all iterations normally. Set to N to halt the loop after iteration N (0-indexed) during editor preview. Not compiled into the binary.

Tips

  • Accumulate mode (default on Loop End) merges each iteration into a growing mesh. Replace mode folds: each iteration transforms the previous result.
  • Pick the loop body: only nodes in the body repeat; everything else runs once. Until you pick, Infinio guesses the body from the wiring and the guess is often wrong. Click Pick body on the amber card (the guess comes pre-selected), click nodes to add or remove them, then Confirm or press Enter. Once picked, + adds the selected nodes and × clears the body. Guide: getinfinio.com/docs/loops/
  • Add Carry channels (CARRY section) to thread a running value: a cursor, accumulating height, or last-tilt flag: from one iteration to the next. For index-only patterns, try Noise1D(Index) instead: no carry needed.
  • Per-node thumbnails inside the loop body show local-space geometry from a single iteration: before any placement transform applied outside the loop.

Loop End

Closes a geometry loop. Accumulate mode stacks each iteration’s geometry; Replace mode folds it. Optional Stop When port exits early when true.

Inputs

  • Geometry (Geometry)
  • Stop When (Bool)
  • carryNexts (Float)

Outputs

  • Geometry (Geometry)

Options

  • pairedLoopBeginGUID: Internal: the GUID of the matching Loop Begin node. Set automatically when the loop pair is established; do not edit directly.
  • mode: Geometry accumulation mode. Accumulate merges each iteration’s output into a growing mesh (tiling, stacking, array patterns). Replace folds: each iteration’s geometry becomes the new accumulator (subdivision, erosion, iterative refinement).

Tips

  • Accumulate (default): merges each iteration’s Geometry into the running accumulator: use for tiling, stacking, and array patterns.
  • Replace: the accumulator becomes this iteration’s geometry: use for iterative refinement such as subdivision or erosion loops.
  • Stop When exits the loop after the current iteration; leave unwired or false to run the full Count.
  • Carry feeds the updated carry value back to Loop Begin’s Carry output for the next iteration. Leave unwired to pass the value through unchanged.
  • To skip an iteration: put a Branch (Geometry) in the loop body with the False arm unwired. The skipped iteration’s work (geometry, scatter, colliders) is not evaluated.
  • To break early: wire the same stop condition into both Stop When and a Branch (Geometry) gate that wraps the body: Stop When keeps the triggering iteration’s geometry; the Branch discards it.

Loop End (Spawn)

Closes a For Each Spawn Point loop. Each iteration optionally overrides the spawn’s position, rotation, scale, variant, or attribute; Filter discards the spawn; Stop When exits early.

Inputs

  • Position (Vector3)
  • Rotation (Vector3)
  • Scale (Float)
  • Variant (Float)
  • Attribute (Float)
  • Stop When (Bool)
  • Filter (Bool)

Outputs

  • Spawn (Scatter)

Options

  • pairedLoopBeginGUID: Internal: the GUID of the matching For Each Spawn Point node. Set automatically; do not edit.

Tips

  • Leave all field ports unwired to pass each spawn through unchanged: every field defaults to the source spawn’s own value.
  • Wire only the fields you want to change: unwired position, rotation, scale, variant, and attribute keep the source spawn’s original value.
  • Wire Rotation only when changing it; an Euler round-trip may not be bit-exact.
  • Filter (true) discards the current spawn from the output list; use it to remove spawns by condition without breaking the iteration.
  • Stop When exits after the current iteration; leave unwired or false to run the full count.
  • The Spawn output is a new scatter list: wire it into a subsequent For Each Spawn Point, a Scatter node consumer, or the top-level output.
  • Attribute is the per-spawn float channel set by ScatterSurface or attribute nodes; read it from For Each Spawn Point’s output.

SubGraphCall

Programmatic use only: not surfaced in palette. Calls an inlined subgraph section via GraphBuilder.SetSubgraphStart().

Outputs

  • Pass-through (Float)

SubGraphGeometry

Inlines another graph and exposes its GeometryOutput as a geometry source. Single-slot exposed parameters (Float/Int/Bool) from the sub-graph appear as wirable input ports.

Inputs

  • dynParams (Float)

Outputs

  • Geometry (Geometry)
  • Geometry 1 (Geometry)
  • Geometry 2 (Geometry)
  • Geometry 3 (Geometry)

Options

  • subGraphSource: The Infinio graph asset to inline at this call-site. Drag from the Project window. Single-slot exposed parameters from the sub-graph appear as wirable input ports on this node.
  • subGraphBinary: Frozen compiled binary: alternative to Source Graph when the sub-graph’s implementation should be locked at a specific compile snapshot. If both Source Graph and this field are assigned, Source Graph wins and this is cleared.
  • _dynParamDefaults: Internal: persisted override values for unwired dynamic parameter ports, keyed by parameter stable name. Managed automatically through port interactions; do not edit directly.
  • randomise: When enabled and the sub-graph’s Seed parameter is unwired, injects a Seed Mix synthesis chain so each call-site produces a distinct seed derived from the Graph Seed. Disable to force all invocations to share the parent graph seed without per-call-site variation. Scope: this reaches the Seed parameter ONLY: it is what varies Random nodes driven from the sub-graph’s Seed port. You do NOT need it for randomised Parameter nodes inside the sub-graph: those already sample a different value per call-site, and per loop iteration when the call-site sits in a loop, whichever way this toggle is set.

Limitations

  • A sub-graph parameter left in a random mode (Range / Gaussian / Chance) gets NO input port here. Its bounds are baked into the binary when the sub-graph is inlined, so there would be nothing for a wire to drive: the port is withheld rather than accepting a wire that does nothing.
  • To drive that value from this graph: set the parameter back to Fixed inside the sub-graph (that restores its input port), then wire a parameter from this graph into it. A randomised parameter authored HERE still varies per call-site, and per loop iteration when the call sits in a loop.

SubGraphPolygon

Inlines another graph and exposes its polygon output. Single-slot exposed parameters (Float/Int/Bool) from the sub-graph appear as wirable input ports.

Inputs

  • dynParams (Float)

Outputs

  • Polygon (Polygon)

Options

  • subGraphSource: The Infinio graph asset to inline at this call-site. Drag from the Project window. Single-slot exposed parameters from the sub-graph appear as wirable input ports on this node.
  • subGraphBinary: Frozen compiled binary: alternative to Source Graph when the sub-graph’s implementation should be locked at a specific compile snapshot. If both are assigned, Source Graph wins and this is cleared.
  • _dynParamDefaults: Internal: persisted override values for unwired dynamic parameter ports, keyed by parameter stable name. Managed automatically through port interactions; do not edit directly.
  • randomise: When enabled and the sub-graph’s Seed parameter is unwired, injects a Seed Mix synthesis chain so each call-site produces a distinct seed derived from the Graph Seed. Disable to force all invocations to share the parent graph seed without per-call-site variation. Scope: this reaches the Seed parameter ONLY: it is what varies Random nodes driven from the sub-graph’s Seed port. You do NOT need it for randomised Parameter nodes inside the sub-graph: those already sample a different value per call-site, and per loop iteration when the call-site sits in a loop, whichever way this toggle is set.

Limitations

  • A sub-graph parameter left in a random mode (Range / Gaussian / Chance) gets NO input port here. Its bounds are baked into the binary when the sub-graph is inlined, so there would be nothing for a wire to drive: the port is withheld rather than accepting a wire that does nothing.
  • To drive that value from this graph: set the parameter back to Fixed inside the sub-graph (that restores its input port), then wire a parameter from this graph into it. A randomised parameter authored HERE still varies per call-site, and per loop iteration when the call sits in a loop.

SubGraphPolygonInput

Retired: wirable Polygon sub-graph port. Existing binaries continue to work. New graphs use the Shape node (Polygon/Shape) which carries the wirable port.

Outputs

  • Polygon (Polygon)

SubGraphScalar

Inlines another graph and exposes its scalar output. Single-slot exposed parameters (Float/Int/Bool) from the sub-graph appear as wirable input ports.

Inputs

  • dynParams (Float)

Outputs

  • Value (Float)

Options

  • subGraphSource: The Infinio graph asset to inline at this call-site. Drag from the Project window. Single-slot exposed parameters from the sub-graph appear as wirable input ports on this node.
  • subGraphBinary: Frozen compiled binary: alternative to Source Graph when the sub-graph’s implementation should be locked at a specific compile snapshot. If both are assigned, Source Graph wins and this is cleared.
  • _dynParamDefaults: Internal: persisted override values for unwired dynamic parameter ports, keyed by parameter stable name. Managed automatically through port interactions; do not edit directly.
  • randomise: When enabled and the sub-graph’s Seed parameter is unwired, injects a Seed Mix synthesis chain so each call-site produces a distinct seed derived from the Graph Seed. Disable to force all invocations to share the parent graph seed without per-call-site variation. Scope: this reaches the Seed parameter ONLY: it is what varies Random nodes driven from the sub-graph’s Seed port. You do NOT need it for randomised Parameter nodes inside the sub-graph: those already sample a different value per call-site, and per loop iteration when the call-site sits in a loop, whichever way this toggle is set.

Limitations

  • A sub-graph parameter left in a random mode (Range / Gaussian / Chance) gets NO input port here. Its bounds are baked into the binary when the sub-graph is inlined, so there would be nothing for a wire to drive: the port is withheld rather than accepting a wire that does nothing.
  • To drive that value from this graph: set the parameter back to Fixed inside the sub-graph (that restores its input port), then wire a parameter from this graph into it. A randomised parameter authored HERE still varies per call-site, and per loop iteration when the call sits in a loop.

Switch (Geometry)

Reads an integer Index and outputs the Geometry at that slot (0–7). The other 7 slots are skipped when they don’t feed anything else: including any collider output inside them.

Inputs

  • Index (Float)
  • Geometry 0 (Geometry)
  • Geometry 1 (Geometry)
  • Geometry 2 (Geometry)
  • Geometry 3 (Geometry)
  • Geometry 4 (Geometry)
  • Geometry 5 (Geometry)
  • Geometry 6 (Geometry)
  • Geometry 7 (Geometry)

Outputs

  • Geometry (Geometry)

Tips

  • Only the selected slot’s chain runs when it isn’t shared with anything outside the switch. A slot feeding a shared node elsewhere runs on every evaluation.
  • The not-selected slots’ geometry, scatter, and collider work is skipped (except SubGraph nodes 910/911/912 which always run).
  • Clamp or modulo Index before wiring to avoid values outside [0, 7]. Values above 7 are clamped to 7.

Switch (Index Select)

Reads an integer Index and returns the input at that slot (0–7). Out-of-range indices are clamped. Both this and Branch always evaluate all upstream nodes.

Inputs

  • Index (Float)
  • Value 0 (Float)
  • Value 1 (Float)
  • Value 2 (Float)
  • Value 3 (Float)
  • Value 4 (Float)
  • Value 5 (Float)
  • Value 6 (Float)
  • Value 7 (Float)

Outputs

  • Result (Float)

Switch (Spawn)

Reads an integer Index and outputs the Spawn points at that slot (0–7). The other 7 slots’ collider work is skipped when it doesn’t feed anything else, but a Scatter Output inside any slot always runs (not yet lazy).

Inputs

  • Index (Float)
  • Spawn 0 (Scatter)
  • Spawn 1 (Scatter)
  • Spawn 2 (Scatter)
  • Spawn 3 (Scatter)
  • Spawn 4 (Scatter)
  • Spawn 5 (Scatter)
  • Spawn 6 (Scatter)
  • Spawn 7 (Scatter)

Outputs

  • Spawn (Scatter)