Recipes
Staggered spawning, a per-frame scan, a curve-driven fade, a pause-menu animation, waiting for an actor with a timeout, an actor that owns its console commands.
Table of contents
- Spawn ten enemies, one every quarter second
- Scan a thousand items without a hitch
- Fade a widget in on an ease-out curve
- Animate a pause menu while the game is paused
- Wait for the boss to exist, but not forever
- An actor that owns its own console commands
Each recipe is a Blueprint graph described as steps, with the pins that matter. Three were built in the editor and show that graph: the thousand-item scan, the fade-in and the boss wait. The others are written from the reference and have not been built as shown, and the C++ snippet at the end is not compiled.
Spawn ten enemies, one every quarter second
- From
Event BeginPlay: For Each Index With Delay —Count=10,Delay=0.25. - From
Loop Body: Spawn Actor from Class, with the transform computed fromIndex(aMake TransformwithIndex × 200on X, for example). - From
Completed: whatever should happen once all ten exist — enable the encounter, play a sound.
Auto Continue stays checked: spawning is synchronous, so the body is done when it returns.
Completed fires right after the tenth spawn — there is no delay after the last
iteration.
To wait until each enemy has finished its intro animation before spawning the next, clear
Auto Continue, and from the end of the intro (a Play Montage’s On Completed, for instance)
call Continue Loop on the loop’s Loop pin. Promote the Loop pin to a variable so the
montage’s completion event can reach it.
Scan a thousand items without a hitch
- For Each Index Per Tick —
Count=1000,Items Per Tick=50. - From
Loop Body: the per-item check, usingIndexto look the item up. - From
Completed: use the results.
The scan takes twenty frames at fifty checks each, so no single frame pays for a thousand. If
fifty checks still stall a frame, lower Items Per Tick; if a check is cheap, raise it — there is
no upper bound.
A body that is latent — an asset load per item, for example — needs Auto Continue cleared and a
Continue Loop when the load finishes, and then runs one item per frame regardless of
Items Per Tick.
Fade a widget in on an ease-out curve
- Create a Curve Float asset; put a key at
(0, 0)and one at(1, 1), and set the second key’s tangent so the curve arrives flat. - Do For Duration —
Duration=0.5,Curve= the asset. - From
On Update: Set Render Opacity on the widget withAlpha. - From
Completed: enable input on the widget.
The last On Update carries the curve’s value at time
1 — here 1.0 — so the widget ends
fully opaque, not at 0.97. Without the curve the alpha is linear and still ends at exactly 1.
To fade out, drive the same node and feed 1 − Alpha into opacity; or author a curve from
(0, 1) to (1, 0).
Animate a pause menu while the game is paused
- Do For Duration —
Duration=0.3; under the advanced arrow, checkTick When Paused. - From
On Update: the menu’s slide-in — aSet Render Translationwith a lerp onAlpha. - Start the node, then call Set Game Paused (
true); the drive keeps running through the pause.
Without Tick When Paused the drive freezes the moment the game pauses and the menu stops
mid-slide. Use Unscaled Time is a separate question, about which clock the drive
integrates — leave it off unless the game also uses time
dilation and you want the menu unaffected by it.
Wait for the boss to exist, but not forever
- Create a Blueprint function
IsBossPresent(whyConditiontakes a function, not an event), inputAttempt(Integer), outputPresent(Boolean). Its body: Get Actor of Class (the boss class) → Is Valid → return. - On the event graph: Wait Until —
Poll Interval=0.5,Timeout=10.0,Check Immediatelychecked. - Drag from
Condition, choose Create Event, pickIsBossPresent. - From
On Satisfied: start the fight. FromOn Timed Out: log the failure and fall back.On Cancelledcan stay unconnected if nothing callsCancel.
Check Immediately means a boss that is already there fires On Satisfied in the same frame.
With Poll Interval at 0.5 and Timeout at 10, the condition is asked once at activation
and then up to nineteen more times. With Poll Interval at 10 or more,
the deadline lands before the first poll is due:
it would be asked only once, at activation, before the node times out.
Keep the function on a Blueprint that outlives the wait. If the object owning IsBossPresent is
destroyed mid-wait, the node fires On Timed Out and logs an
Error.
An actor that owns its own console commands
- In the actor’s
BeginPlay: Get Console Command Registry → Register Console Command withName=MyGame.Debug.KillMe,Help=Destroys this actor, andCallbackbound to a custom event on the actor with oneArgs(Array of String) pin. - In the custom event: Destroy Actor.
- In
EndPlay: Get Console Command Registry → Unregister Commands For withOwner=self.
The registry holds the actor
weakly, so a forgotten
EndPlay half of the pair is not a crash — the command does nothing once the actor is gone, and
the registry sweeps it out at the next registration. Unregister Commands For is still the right
thing to do: it removes the console entry the moment the actor leaves, instead of leaving a dead
name listed until something else registers.
Two actors of the same class register the same name; the second one’s registration returns
false. Put the actor’s name into the command name (MyGame.Debug.Kill.<Name>), or register the
command once from the registry’s Blueprint child and have it find the actor by argument.
From C++, the same recipe binds a UFUNCTION with the signature
void HandleCommand(const TArray<FString>& Args):
FSCBlueprintConsoleCommand Callback;
Callback.BindDynamic(this, &AMyActor::HandleCommand);
if (USCConsoleCommandRegistrySubsystem* Registry = USCConsoleCommandRegistrySubsystem::Resolve(this))
{
Registry->RegisterConsoleCommand(TEXT("MyGame.Debug.KillMe"), TEXT("Destroys this actor"), Callback);
}
// in EndPlay:
if (USCConsoleCommandRegistrySubsystem* Registry = USCConsoleCommandRegistrySubsystem::Resolve(this))
{
Registry->UnregisterCommandsFor(this);
}