What a waste of time

so I spent two days to realize i should just use a interface but can some one explain if its possible to make this work without interface what about using two overlap components one for left ai and one to right for player?

there are other ways, ActorComponent or Tags but they both require change and are probably worse. An interface is quick and easy to implement


:brain: 1. The Core Problem We’re Solving

Your door is reacting to two possible actors overlapping it:

  • :person_standing: Player

  • :robot: AI Buyer

But Unreal’s OnComponentBeginOverlap only fires once per actor — and actors can enter in any order.
So your biggest enemy is this:

“Who overlaps first, and what if the other actor isn’t there yet?”

If you run logic immediately when one enters, you’ll hit Accessed None or invalid reference errors.

So the challenge was:

  • Track both actors independently

  • Only run the “handshake logic” when both are present

  • Avoid re-triggering it multiple times


:gear: 2. Why the HasTriggered Boolean Exists

That’s our safety lock.

Without it, Unreal fires multiple overlaps — e.g.:

  • AI steps in → overlap fires

  • Player steps in → overlap fires again

  • Maybe the AI slightly moves → fires again

  • Boom: widget spam, logic repeats, errors pile up

So we add a simple gatekeeper:

if NOT HasTriggered:
    (run logic)
else:
    ignore

This is a classic pattern in UE and all event-driven systems.


:repeat_button: 3. Why We Use a Sequence

Because you want to check both AI and Player overlaps every time an overlap happens.

Unreal only gives you one Other Actor per overlap event — but you don’t know who it is until you test.

So the Sequence node splits execution:

Exec 0 → Try AI Cast
Exec 1 → Try Player Cast

Each “exec” checks one possibility separately — it’s like saying:

“Let’s see if this was an AI. No? Okay, maybe it was the Player.”

That’s way cleaner and safer than putting both casts on one line.


:puzzle_piece: 4. Why Each Side Calls CheckBothOverlap()

Because each overlap event could be the second half of the handshake.

  • If the AI enters first, we store them and wait for the player.

  • If the Player enters first, we store them and wait for the AI.

Then, every time a new overlap happens, we call:

CheckBothOverlap()

That function checks:

if (PlayerRef != None) AND (CurrentCustomer != None)

When both exist → the deal is ready.

That means no matter who walks in first, it always synchronizes cleanly.


:locked: 5. Why It’s So Reliable

This pattern combines three concepts:

Concept Why it matters
NOT HasTriggered Prevents duplicate firings
Sequence Separates logic for AI vs Player
CheckBothOverlap() Waits until both actors exist

These three together create safe, event-driven interaction logic — no timers, no hard dependencies, no invalid refs.
It’s exactly how professionals design door triggers, quest givers, or dialogue initiators in open-world games.


:speech_balloon: Real-world Dev Insight

This logic pattern — it’s universal:

  • RPG quest givers (player + NPC proximity)

  • Store counters (cashier + customer detection)

  • AI conversations

  • Door unlock systems (key + player overlap)

  • Coop puzzles (two players step on plates)

So by understanding this pattern, you’ve learned a core interaction architecture you’ll reuse in every future UE project.