Hit That Cue: Triggered Sound Effects
Tutorial intermediate compiles

Hit That Cue: Triggered Sound Effects

Updated intermediate Scene Graph Sound Code verified

Hit That Cue: Triggered Sound Effects

In Part 1 we laid down an ambient bed that plays forever. But the sounds that make a space feel interactive are the ones that fire in response to the player: a whoosh as they cross the dance floor, a chime as they hit a tile, a thump as the entrance doors part. These are one-shot sound effects — they play once, on cue.

The cue we'll use is the most common one in Fortnite: a player stepping into a Trigger Device's zone.

The club entrance pad — a Trigger Device wired to a stinger Audio Player

The pattern: an event you wait on

<!-- section-art:the-pattern-an-event-you-wait-on --> Hit That Cue: Triggered Sound Effects: The pattern: an event you wait on

Frozen Sound Trap

A Trigger Device is an invisible volume. When an agent enters it, the device fires its TriggeredEvent. In Verse you don't poll "is anyone in the zone?" every frame — you wait on the event and react when it fires:

# A Trigger Device fires its TriggeredEvent when an agent steps into its zone.
# Await() it inside a loop and you have a clean "when a player enters, do X"
# hook — here, play a one-shot sound effect. The event hands you a ?agent
# (the player who stepped in), which you can pass to a per-player Play.
loop:
    MaybeAgent := EntryPad.TriggeredEvent.Await()
    StingerSfx.Play()

Await() parks the code right there — burning zero CPU — until the trigger fires. The moment a player enters, execution resumes, we play the sound, and loop sends us back to wait for the next player. This is the event-driven style: react to things happening, never busy-wait.

Await() requires a <suspends> context — code that's allowed to pause and resume over time. OnBegin<override>()<suspends> is exactly that, which is why every device's OnBegin is marked <suspends>.

The full entry-stinger device

Wire a Trigger Device (the entry pad) and an Audio Player Device (the stinger) into the slots, and every entry fires the cue:

The two new ideas:

1. The event carries the player. TriggeredEvent sends a ?agent — an optional agent. It's false when the trigger was fired by code rather than a person. if (Agent := MaybeAgent?) unwraps it: the ? postfix says "if this option holds a value, bind it to Agent." Inside the if, we know exactly who stepped in.

2. Play for one player, or for all. The Audio Player Device has two Play forms:

  • Play() — plays the sound out into the world, heard by everyone in range.
  • Play(Agent) — plays the sound just for that agent. This only works when the device is set to Heard by Instigator in its options. Perfect for a personal pickup chime or a UI confirmation that shouldn't bother the whole lobby.

We use Play(Agent) when we have a real player, and fall back to Play() otherwise.

One-shot vs. looping — same device, different asset

Nothing in the code makes this a one-shot rather than a loop — that's set by the sound asset and the device's loop option. For a stinger you assign a short, non-looping clip; for the ambient bed in Part 1 you assigned a looping one. The same audio_player_device and the same Play() serve both; the asset decides whether you hear a single thump or an endless hum.

A player crossing the dance-floor trigger zone, firing the stinger

Designing good audio cues

<!-- section-art:designing-good-audio-cues --> Hit That Cue: Triggered Sound Effects: Designing good audio cues

Personal Audio Cues

A few habits that make triggered audio feel professional:

  • Keep stingers short. A cue that overstays its welcome turns into noise. Sub-second clips read as "feedback"; long ones read as "music."
  • Don't stack identical cues. If a tile can be re-triggered rapidly, either gate it with a cooldown or accept that the engine will retrigger the clip from the top each time.
  • Use Play(Agent) for personal feedback. A coin chime or "door unlocked" should reward the player who earned it — not blast the entire server.

Recap

  • A Trigger Device fires TriggeredEvent when an agent enters its zone; Await() it in a loop to react without polling.
  • The event sends a ?agent — unwrap with if (Agent := MaybeAgent?) to learn who triggered it.
  • Play() is heard by everyone; Play(Agent) plays just for one player (device must be Heard by Instigator).
  • One-shot vs. looping is decided by the asset, not the code.

Next — Part 3: Drop the Beat — we move from sound effects to looping music with the Radio Device, registering players so the whole club hears the set.

Get the complete code — free

You've read the full walkthrough. The complete, copy-paste-ready Verse solution is free for members — sign in to unlock it.

Free with your BrainDead.TV / BrainDeadGuild Discord account. The walkthrough above is always free.

Verse source files

Check your understanding

Test yourself with an interactive quiz and track your progress + earn XP — free for members.

Up next · Scene Graph: Sound Drop the Beat: Music & Loops with the Radio Device Continue →

Turn this into a guided course

Add UEFN audio — trigger_device, TriggeredEvent, one-shot SFX, per-player Play(agent) to your free study plan — we'll suggest related pages and stitch the lot into one compile-checked, self-guided lesson with worked examples and quizzes.

Original tutorial generated by Verse Island from the Verse/UEFN knowledge base, with references to the Epic Games sources above. Code is validated against the knowledge base.

Comments

    Sign in to vote, comment, or suggest an edit. Sign in