For Each Index
For Each Index With Delay and For Each Index Per Tick — the loop node, its latent-body protocol, Continue Loop and Break Loop.
Table of contents
USCFlowForEachIndexWithDelayFor Each Index With DelayFor Each Index Per TickAuto Continueand the latent-body protocol- Functions
- Outputs
- Messages
- Pitfalls
USCFlowForEachIndexWithDelay
Available in: C++ and Blueprint. UBlueprintAsyncActionBase, BlueprintType, proxy pin
Loop. Module StillCookingCore, header Flow/SCFlowForEachIndexWithDelay.h. Category
StillCooking|Flow. Built on FSCFlowLoop.
Two palette entries, both created from this class, both running a body once per index from 0
to Count − 1. They differ in what separates one iteration from the next: a delay on the clock,
or the next frame.
For Each Index With Delay
- C++ call —
USCFlowForEachIndexWithDelay::ForEachIndexWithDelay(WorldContextObject, Count, Delay, bDelayBeforeFirstIteration, bAutoContinue), thenActivate() - Blueprint node —
For Each Index With Delay
| Parameter | Pin | Default | Meaning |
|---|---|---|---|
WorldContextObject | hidden | — | filled in by self |
Count | Count | none in C++; the pin shows 0 | number of iterations; 0 or less completes during activation, without a single iteration |
Delay | Delay | 0.2 | seconds between the end of one iteration and the start of the next; 0 or less means the next tick |
bDelayBeforeFirstIteration | Delay Before First Iteration | false | wait one Delay before index 0 as well |
bAutoContinue | Auto Continue | true | advanced; see below |
The first iteration lands on the first tick after activation, never
synchronously. The delay clock runs only between iterations: with Auto Continue cleared, it does not advance while a latent body is in flight.
After a hitch longer than several delays, one iteration runs, not a burst; the part of the hitch
below one Delay carries into the next wait. There is no delay after the last iteration;
Completed follows it immediately, and a trailing pause is a Delay node after Completed.
For Each Index Per Tick
- C++ call —
USCFlowForEachIndexWithDelay::ForEachIndexPerTick(WorldContextObject, Count, ItemsPerTick, bAutoContinue), thenActivate() - Blueprint node —
For Each Index Per Tick
| Parameter | Pin | Default | Meaning |
|---|---|---|---|
WorldContextObject | hidden | — | filled in by self |
Count | Count | none in C++; the pin shows 0 | number of iterations; 0 or less completes during activation, without a single iteration |
ItemsPerTick | Items Per Tick | 1 | iterations per frame; values below 1 are treated as 1; there is no upper bound |
bAutoContinue | Auto Continue | true | advanced; see below |
Runs ItemsPerTick iterations in one frame, then waits for the next frame. The node has no
Delay pin. Use it when one iteration is cheap and you want the whole loop to finish in a few
frames without stalling any one of them. A value at or above Count runs the whole loop in one
frame; there is no upper bound.
With Auto Continue cleared, ItemsPerTick has no effect. A suspended body ends the current batch, and the rest of the batch is skipped, not made up later — the loop degrades to
one iteration per frame by itself.
Auto Continue and the latent-body protocol
Loop Body is a delegate; the node broadcasts it once per index and cannot see what the graph
does with it. Two kinds of body exist:
- A synchronous body — a chain of ordinary nodes — has finished when the broadcast returns.
- A latent body — one containing a
Delay, aMove Component To, an asset load — has returned long before it has finished.
Auto Continue checked (the default): the loop moves on as soon as the broadcast returns.
Right for a synchronous body, which then needs nothing beyond the loop itself. With a latent
body, the loop does not wait: the next iteration starts on schedule while the previous body is
still in flight.
Auto Continue cleared: the loop parks after each broadcast and waits for Continue Loop.
Right for a latent body: call Continue Loop on the Loop pin as the last thing the body does.
A body that never sends one parks the loop for good — and after 30 seconds the loop logs a
Warning saying exactly that.
Calling Continue Loop while Auto Continue is checked is safe: the loop counts one advance for
the iteration, not two. A Continue Loop sent mid-delay, between iterations, is ignored rather
than skipping a body call.
The default is checked because the other default failed silently: a synchronous body with the Loop pin left unconnected ran one iteration and stopped forever, with no error and no log.
Checked, a synchronous body needs nothing; cleared, a latent body needs one checkbox and one
call — and a forgotten call now produces a warning.
Functions
Continue()
C++ · Blueprint
- C++
Node->Continue()- Blueprint
Continue Loop
- Takes
- no parameters
- Returns
- returns nothing
Delay is 0, otherwise once the delay has elapsed. Does nothing when the
loop is not waiting for it: under Auto Continue, or between iterations. On the last index there
is no next iteration: a Continue Loop sent after the body returned ends the loop inside the
call, and Completed fires before Continue Loop returns.
Link to this entry
Break()
C++ · Blueprint
- C++
Node->Break()- Blueprint
Break Loop
- Takes
- no parameters
- Returns
- returns nothing
Completed — the same pin as a full run; in Blueprint
nothing tells the two apart. Works in
either mode, from inside the body or from anywhere else that holds the Loop pin. From anywhere
else, Completed fires before Break Loop returns. A Break Loop from inside the
body is applied after the body returns, and wins over a Continue Loop sent from the same body.
A second Break Loop is a no-op.
Link to this entryOutputs
| Pin / delegate | Type | When |
|---|---|---|
Loop Body (LoopBody) | FSCFlowIndexSignature(int32 Index) | once per index, zero-based |
Completed (Completed) | FSCFlowCompletedSignature(bool bCompletedFully) | once, when the loop ends; bCompletedFully is false when Break Loop stopped it early — C++ only, the Blueprint node has no pin for it |
Loop | USCFlowForEachIndexWithDelay* | the node itself, for Continue Loop and Break Loop — the proxy pin every Flow node carries |
Completed does not fire when the world is torn down under the
loop.
In Blueprint the node’s only data pin is Index, from Loop Body. On the Completed path it
still holds the last index delivered, or 0 if none was —
why Completed carries no reason.
Messages
Two of the plugin’s own, both on LogStillCooking, plus one from the engine. The exact wording
of the suspended-loop warning, of
the message every Flow node can write and of
the engine’s warning that precedes it on the loop nodes:
| When | Level |
|---|---|
Auto Continue is cleared and no Continue Loop arrives for longer than the threshold | Warning, once per loop |
| the world context resolved no world, so nothing fires | Error |
| the same, reported first by the engine’s world lookup, which names the world context object | Warning, engine’s own |
The threshold is the console variable SC.Flow.SuspendedLoopWarningSeconds; 0 or less disables
the warning — why it is a variable and not a
pin. The warning fires once per loop
instance and never again, even across several suspensions; a loop resumed under the threshold
says nothing, and the clock restarts on each suspension.
Pitfalls
- One iteration, then silence is a latent body with
Auto Continuecleared and noContinue Loop. Wait for the warning or check the graph. - A latent body under
Auto Continueis not waited for — the next body starts on schedule while the previous one is still in flight. ClearAuto Continueif that is not what you want. Delay=0on the delayed node is one iteration per tick, the same as the per-tick node atItems Per Tick=1.Delay Before First Iterationdefers index0by oneDelay; without it index0runs on the first tick regardless ofDelay.