On Component Begin / End Overlap¶
At a glance
Lives in: Blueprint API / Collision -
Runs on: a PrimitiveComponent overlap pair -
Returns: no value; it starts execution when the component begins or
stops overlapping another component -
Fails by: never firing, usually silently -
Needs: compatible collision responses, query collision, and Generate
Overlap Events on both relevant components -
Official docs: On Component Begin Overlap
and On Component End Overlap
The one-minute version¶
On Component Begin Overlapfires when this component starts overlapping another component.On Component End Overlapfires when that tracked component pair stops overlapping.- The event is component-level, not actor-level.
Other Actoris the actor on the other side;Other Compis the exact component on that actor. - The usual "why does it never fire?" answer is: Generate Overlap Events is off on one of the two components, collision is not query-enabled, or the pair is set to Ignore/Block instead of a reliable overlap setup.
- The usual "why does it fire twice?" answer is: more than one component pair overlapped. A character capsule and mesh can both touch the same trigger if both are set up to overlap it.
- The event does not filter for you. Cast, compare, tag-check, or interface-call
from
Other Actorbefore running gameplay logic. - In multiplayer, overlap events are local to the world that detects them. Put authoritative gameplay changes on the server and replicate the result.
What it actually does¶
Primitive components keep track of which other primitive components they are currently overlapping. When movement, registration, spawning, or a collision setting update creates a new overlap pair, the engine can add that pair to the component's overlap list and send begin-overlap notifications. When that pair is no longer overlapping, the engine can remove it and send end-overlap notifications.
pseudocode of the engine behavior - not engine source
function UpdateOverlaps(ThisComponent):
NewPairs = find components now overlapping ThisComponent
for Pair in NewPairs not already tracked:
track Pair
if notifications are enabled:
fire OnComponentBeginOverlap
for Pair in tracked pairs no longer in NewPairs:
untrack Pair
if notifications are enabled:
fire OnComponentEndOverlap
Blueprint shows that as two events tied to one component:
BoxCollision.OnComponentBeginOverlap
Overlapped Component = BoxCollision
Other Actor = the actor that entered
Other Comp = the component on that actor that overlapped
From Sweep = whether this begin came from a swept move
Sweep Result = hit-style details for swept begin overlaps
BoxCollision.OnComponentEndOverlap
Overlapped Component = BoxCollision
Other Actor = the actor that left
Other Comp = the component on that actor that stopped overlapping
That Other Comp pin is not trivia. If Other Actor is your character,
Other Comp might be the capsule, the mesh, a weapon hitbox, or another
collision shape. A lot of duplicate events are really different component
pairs doing exactly what you asked.
flowchart LR
Trigger[Door Trigger Box] -- overlaps --> Capsule[Player Capsule]
Trigger -- also overlaps --> Mesh[Player Mesh]
Capsule --> Player[BP_PlayerCharacter]
Mesh --> Player
In that diagram, a component-level begin overlap on the trigger can run once
for the capsule and once for the mesh. Both have the same Other Actor; they
do not have the same Other Comp.
When it fails (and what failure does)¶
Overlap events have no Failed pin. The normal failure mode is silence: no event runs, no retry happens, and no warning is guaranteed.
Common causes:
- Generate Overlap Events is off on either component. The official docs call out both sides. Check the trigger component and the component entering it.
- The pair does not resolve to overlap. For a normal trigger setup, set at least one side to Overlap and neither side to Ignore for the relevant object type. If both sides Block, use a hit event for blocking contact instead of treating it as a trigger.
- Collision Enabled is wrong. Overlaps are query-style collision. A
component with
NoCollisionor physics-only behavior is not a reliable overlap trigger. - You listened on the wrong component. Adding the event to the actor's mesh does not listen to the capsule. Adding it to the trigger box does not listen to a separate child shape.
- The overlapping component has no usable collision shape. A mesh or custom component can have responses that look right while the underlying collision data does not support the query you expect.
- The overlap already existed before you bound your handler. If you bind dynamically after two components are already overlapping, the begin moment may already be gone. Query current overlaps during setup if that starting state matters.
- You are watching the wrong machine or instance. A client-side overlap does not automatically mean the server ran the same event, and a different placed instance of the Blueprint can have different component settings.
Failure does not damage anything, open the door, call End Overlap first, or
cast Other Actor for you. Your graph only runs when the event actually fires.
Filtering the flood¶
The beginner pattern is not "anything that overlaps the trigger opens the door." The pattern is:
OnComponentBeginOverlap(BoxCollision)
-> Other Actor
-> Cast To BP_PlayerCharacter
Success: open the door
Failed: do nothing
If casts are getting noisy, use a clearer contract:
OnComponentBeginOverlap(BoxCollision)
-> Other Actor
-> Does Implement Interface (BPI_InteractTriggerUser)
-> Interface Message: EnteredTrigger
For tags, check the thing you truly mean. Actor tags live on the actor.
Component tags live on the component. If the distinction matters, use
Other Comp instead of only Other Actor.
For duplicate begin/end pairs, filter by component:
Other Actor -> Cast To BP_PlayerCharacter
Other Comp -> Equal Object -> player's CapsuleComponent
Branch both true
-> Start overlap logic once
For "stay inside and apply damage every second," do not apply damage directly from Tick. Track the overlap and use a timer:
BeginOverlap lava volume
-> Cast to BP_PlayerCharacter
-> Add player to OverlappingPlayers set
-> if timer not active, Set Timer by Event every 1.0 seconds
Timer event
-> ForEach OverlappingPlayers
-> Is Valid
-> Apply Damage
EndOverlap
-> Remove player from OverlappingPlayers set
-> if set empty, Clear Timer
That way Begin/End answer "who is inside?", and the timer answers "when should damage tick?"
What End Overlap really means¶
End Overlap means this tracked component pair is no longer overlapping. It
does not necessarily mean "the player intentionally left the room."
End can happen because:
- the actor walked out;
- one component was moved, destroyed, disabled, or unregistered;
- collision settings changed so the pair no longer overlaps;
- a streamed level, despawn, or respawn removed one side from the world.
That is why End Overlap is good for local cleanup such as "stop highlighting," "remove from the set," or "clear this timer if nobody is inside." It is a poor place to assume a story beat happened unless your own gameplay state proves that story.
What overlap events do not do¶
- They do not block movement. If you need the actor to stop, configure Block and use hit/sweep behavior.
- They do not apply damage. Call the appropriate damage node yourself.
- They do not filter by class, tag, team, owner, or player index.
- They do not run exactly once per actor. They run per component overlap pair.
- They do not replicate. Server and client worlds can observe different local overlaps; authoritative state still belongs on the server.
- They do not replace current-state queries. If you need to know "who is already inside right now," query the current overlaps or maintain a set.
The pattern everyone actually uses¶
For a pickup:
PickupSphere.OnComponentBeginOverlap
-> Other Actor
-> Cast To BP_PlayerCharacter
-> Give item / add score on the server or in single-player
-> Destroy pickup actor
For a door trigger:
TriggerBox.OnComponentBeginOverlap
-> Other Actor
-> Cast To BP_PlayerCharacter
-> Add to OverlappingPlayers
-> Open Door
TriggerBox.OnComponentEndOverlap
-> Other Actor
-> Cast To BP_PlayerCharacter
-> Remove from OverlappingPlayers
-> if OverlappingPlayers is empty: Close Door
For C++, bind the component delegate and keep the same guard:
void ATrainingDoor::BeginPlay()
{
Super::BeginPlay();
TriggerBox->OnComponentBeginOverlap.AddDynamic(
this, &ATrainingDoor::HandleTriggerBegin);
}
void ATrainingDoor::HandleTriggerBegin(
UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex,
bool bFromSweep,
const FHitResult& SweepResult)
{
ATrainingCharacter* Character = Cast<ATrainingCharacter>(OtherActor);
if (!IsValid(Character))
{
return;
}
OpenDoor();
}
Lookalikes - which one do I want?¶
| Event or query | Use when | Watch out |
|---|---|---|
| On Component Begin Overlap | One specific component should react when another component enters it. | Fires per component pair. |
| On Component End Overlap | You need cleanup when that component pair separates. | End can also come from destruction, collision changes, or unregistering. |
| On Actor Begin / End Overlap | Actor-level overlap is enough and component identity does not matter. | Easier, but hides which component caused the interaction. |
| Event Hit / On Component Hit | You need blocking contact, impact normals, or physics/sweep hits. | Hit is not a trigger overlap. |
| Is Overlapping Actor / Component | You need to ask about current state now. | It does not tell you when the state changed. |
| Get Overlapping Actors / Components | You need everyone currently inside a volume. | It is a query, not an event; do not spam it when an event-maintained set works. |
| Line Trace By Channel | You need a one-shot ray/sweep question, such as "what am I aiming at?" | A trace has a trace channel, not an object type. |
Rule of thumb: use component overlap events for trigger volumes and area
detection; filter Other Actor, and inspect Other Comp when the event count
surprises you.
Going deeper¶
- Collision presets, channels, and responses - the settings that decide whether an overlap pair exists in the first place.
- Event AnyDamage / Apply Damage - a common next step after an overlap detects a valid target.
- Cast To X - the beginner filter after
Other Actor. - Is Valid - guard stored overlap references before using them later from a timer.
- The frame: Tick, timers, and timelines - use timers for periodic overlap effects instead of Tick polling.
- Official docs: On Component Begin Overlap, On Component End Overlap, Component Overlap Components, Is Overlapping Component, UPrimitiveComponent::BeginComponentOverlap, UPrimitiveComponent::EndComponentOverlap, and UPrimitiveComponent.
- Engine source (requires engine access - we do not reproduce it here):
overlap tracking and notification functions such as
UPrimitiveComponent::BeginComponentOverlap,UPrimitiveComponent::EndComponentOverlap,UPrimitiveComponent::UpdateOverlapsImpl, andUPrimitiveComponent::OnGenerateOverlapEventsChangedinEngine/Source/Runtime/Engine/Private/Components/PrimitiveComponent.cpp; declarations and Blueprint delegate fields inEngine/Source/Runtime/Engine/Classes/Components/PrimitiveComponent.h.