Skip to content

Event BeginPlay / Event Tick / Event EndPlay / Set Actor Tick Enabled

At a glance

Lives in: Blueprint API / Add Event and Actor / Tick - Target: Actor - Returns: events return execution pins; Tick also provides Delta Seconds; Set Actor Tick Enabled returns no value - Fails by: not firing, firing later than you expected, or disabling only actor tick - Official docs: Event BeginPlay, Event Tick, Actor Ticking, and SetActorTickEnabled

The one-minute version

  • Event BeginPlay fires once for an actor when that actor begins gameplay in a world.
  • Event Tick fires every frame only if that actor's tick is registered and enabled. Its Delta Seconds pin is the time since the actor's previous tick.
  • Event EndPlay fires when the actor leaves play: destroyed, level unloaded, play ended, or another engine cleanup reason.
  • Set Actor Tick Enabled toggles the actor's own tick function. It does not enable components, timers, animations, or other actors.
  • BeginPlay is not Construction Script. Tick is not a timer. EndPlay is cleanup, not a place to start new gameplay.
  • These events do not prove other actors are ready, do not run on destroyed references, and do not make per-frame work cheap.

What they actually do

The useful order is:

flowchart LR
    Spawn[Actor enters play] --> Begin[BeginPlay once]
    Begin --> Tick[Tick zero or more times]
    Tick --> End[EndPlay once as it leaves play]

For an actor that ticks:

pseudocode of the engine behavior - not engine source

when Actor begins play:
    call ReceiveBeginPlay / Event BeginPlay once

each world frame:
    if ActorTick is registered and enabled:
        if TickInterval has elapsed:
            call Tick(DeltaSeconds)

when Actor exits play:
    call EndPlay(Reason)

Delta Seconds is frame time for that tick, not a speed by itself. You use it to make per-frame motion independent of frame rate:

NewLocation = CurrentLocation + Direction * SpeedUnitsPerSecond * DeltaSeconds

The broader frame model is covered in The frame: Tick, timers, and timelines.

When they fail (and what failure does)

"My event did not run" usually means one of these:

  1. The graph is in the wrong object. The actor you are watching is not the instance that exists in the level.
  2. The actor has not entered gameplay yet. Construction Script/editor preview work is earlier than BeginPlay.
  3. Tick is disabled by defaults. Some actors or components do not tick unless Can Ever Tick and tick enabled are set.
  4. You disabled only actor tick. Components have their own tick functions. Turning off actor tick does not automatically stop a Niagara system, audio component, animation update, timer, or movement component.
  5. Tick interval delays execution. A tick interval makes the event fire less often than every rendered frame.
  6. The actor was destroyed or its level unloaded. EndPlay is the last cleanup signal; object references elsewhere may now be stale.
  7. BeginPlay ordering surprised you. Other actors may have BeginPlay before or after this one. If you need a reference, assign it deliberately or retry through a known event rather than assuming global order.

Failure usually looks like silence. The engine does not create a missing actor, does not call Tick while disabled, and does not retry a failed cast inside your BeginPlay graph.

The pattern everyone actually uses

Use BeginPlay for setup that must happen at runtime:

BeginPlay
-> get assigned references
-> bind dispatchers
-> create one widget/component/runtime helper if this actor owns it
-> start timers or initial AI setup

Use Tick only for work that really depends on every frame:

Tick(Delta Seconds)
-> update aim trace / camera smoothing / debug-only visual
-> multiply movement by Delta Seconds
-> exit early when inactive

Use timers, events, or dispatchers for repeated gameplay that does not need every frame:

BeginPlay
-> Set Timer by Event every 0.25 seconds
-> scan nearby targets / apply poison tick / update cooldown

Use EndPlay for cleanup:

EndPlay
-> clear timers owned by this actor
-> unbind from external dispatchers
-> tell manager/component that this actor is no longer active

The C++ twin, for the curious (our own example code):

void AScanActor::BeginPlay()
{
    Super::BeginPlay();
    SetActorTickEnabled(false);
}

void AScanActor::SetScanning(bool bScanning)
{
    SetActorTickEnabled(bScanning);
}

void AScanActor::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);
    UpdateScan(DeltaSeconds);
}

EndPlay reasons matter

Blueprint's Event EndPlay gives an EndPlay Reason. For beginner cleanup, the exact enum is less important than the shape:

  • Destroyed actor: clear references and unregister from managers.
  • Level transition or streamed-level unload: do not keep old actor references in GameInstance or SaveGame.
  • End of play-in-editor: expect cleanup to run while the editor is stopping.

Do not start a long Delay, open UI, or spawn replacement gameplay actors from EndPlay as your normal path. Trigger replacement from the owner that decided death, respawn, or travel.

Lookalikes - which one do I want?

Node / event Runs when Use when
Construction Script Editor construction and spawn construction You are configuring components or previewable setup before gameplay.
Event BeginPlay Actor enters gameplay once Runtime initialization, binding, first references.
Event Tick Repeated actor tick while enabled Frame-dependent movement, traces, smoothing, or temporary debug.
Set Actor Tick Enabled Immediately changes actor tick enabled state You want this actor's Tick to pause/resume.
Set Component Tick Enabled Changes a component tick The repeated work lives in a component.
Set Timer by Event Schedules later/repeated callbacks Cooldowns, poison ticks, delayed respawn, periodic scans.
Timeline Plays an authored curve over time Doors, fades, charge bars, and reversible motion.
Event EndPlay Actor leaves play Cleanup external bindings, timers, and manager registration.

Rule of thumb: BeginPlay sets up, Tick updates only what must be per-frame, timers handle periodic gameplay, and EndPlay cleans up.

Going deeper