[UE5] Three Ways Actors Communicate: Direct Reference, Interface, and Event Dispatcher

Created: 2025-12-12Last updated: 2026-09-05

Organizes Blueprint communication into three: calling the target's logic directly, asking via a shared operation name, and notifying registered listeners. A hands-on exercise raising a bridge with the E key clarifies references, Target, and Bind.

"Press the switch and I want the door to open." The intent is simple, but how does the switch tell the door to open?

We call this kind of asking another Blueprint to do something, or telling it something happened communication here. Not network communication for online play, but coordination between parts inside the same game.

The three representative methods are Direct Reference, Blueprint Interface, and Event Dispatcher. Picturing a direct phone line, a standard request form, and a broadcast to people who signed up captures each of their roles. At the end we combine all three into a mechanism where "operating a button makes a bridge appear."

Two figures talking on a tin-can telephone, plus an envelope and a megaphone. An image of ways Blueprints communicate

What You'll Learn

  • The difference between asking a target to do something and telling it something happened
  • What "reference" and "Target" mean, which all three methods need
  • How to set the Interface destination and how to register a Dispatcher listener
  • Hands-on using all three in one mechanism, then adding another listener afterwards

Sponsored

The big picture: what do you want to tell whom

First, a Reference is a value pointing at "the specific instance I want to act on right now." Place two doors from the same plan in the level and the right door and the left door are different references.

Target on a node is the object that performs the operation. Pass the right door to OpenDoor's Target and you are asking the right door to open. Set Target to self and the object is you.

MethodHow we say it hereExample
Direct ReferenceCall the target's specific logicCall this bridge's Extend
InterfaceAsk through a shared operation nameSend Interact to the chosen target
Event DispatcherTell listeners something happenedNotify that the bridge opened

Direct Reference is not the only method that uses a reference. Interface needs a destination too. With a Dispatcher, you use a reference to the sender when setting up to receive.

Direct Reference calls the target's logic directly, Interface asks via a shared operation name, and Dispatcher tells registered listeners. Each needs its own reference

Direct Reference: call the target's logic directly

This method calls a function or Custom Event on that Class directly through a reference to the target. For example, give a switch an Object Reference variable TargetDoor of type BP_Door and call OpenDoor through that reference.

It is a direct phone line saying "run OpenDoor on this door." Which node is being called stays visible, and it suits mechanisms that pair a specific switch with a specific door (→ Level Blueprints and references to placed Actors).

On the other hand, a design that calls BP_Door's OpenDoor needs a target that can be treated as a BP_Door. It will not necessarily drop onto a chest built differently. How much you depend on the target's construction like this is called coupling. Depending on a lot is tight coupling; depending on little is loose coupling.

BP_Switch calls OpenDoor through the TargetDoor reference. It cannot be swapped onto BP_Chest, which has no such function

Calling directly is not bad in itself. You can swap the reference to a different door of the same Class, or call several doors in turn. It is not limited to "only works when there is exactly one forever."

Blueprint Interface: ask through a shared operation name

A Blueprint Interface is a mechanism that standardizes the operation names a target accepts and the values passed. Define a request called Interact for example, and each Actor builds its own reaction: the door opens, the chest reveals its contents, the lever flips.

The sender only has to write "ask this target to Interact," with no need to hunt through door-specific, chest-specific, and lever-specific logic. Picture handing a request form in a standard format to the target you chose.

The same operation name Interact works on a door, a chest, and a lever. Each Actor decides its actual reaction

The diagram lines up examples of targets that can respond. One Message does not automatically broadcast to all three. You specify one target to operate on in the Message's Target.

To use it, line up these four things.

  1. Create a Blueprint Interface and define a function name such as Interact.
  2. Add that Interface to the receiver's Class Settings.
  3. Write the receiver's reaction to that operation.
  4. On the sender, create Interact (Message) and pass the target's reference to Target.

If the target you sent a Message to does not implement the Interface, the operation simply ends with nothing happening. When "the wires connect but nothing responds," check the receiver's Interface addition and implementation in addition to Target.

Interfaces can also define functions that return values. Start by trying a one-way request with a no-input, no-output Interact, and continue to the Blueprint Interface article for more.

Sponsored

Event Dispatcher: tell registered listeners

An Event Dispatcher is a mechanism for telling events that signed up to receive it about occurrences such as "the bridge opened" or "HP changed."

Sending the notification is Call; registering an event to receive it is Bind. In the broadcast analogy, the receiving side decides up front "which sender's programming do I tune into."

Registered display, audio, and achievement listeners receiving an Event Dispatcher notification

For example, give the bridge an OnBridgeExtended and have the display handler and the audio handler each Bind to that bridge's Dispatcher. When the bridge Calls, both react, without the bridge's opening logic having to say "show this UI and call this audio handler."

This broadcast does not reach every Actor in the game unconditionally. Only events registered to that instance's Dispatcher are called. You can register just one, or several.

Also, notifications sent before you Bind are not replayed afterwards. Finishing registration before moving the bridge is an ordering we confirm in the hands-on (→ Binding and unbinding Event Dispatchers).

Choosing: look at the role, not the number

Splitting by count — "one target means Direct, several means Dispatcher" — leaves you second-guessing. Start by asking what this particular message is trying to do.

What you want to doRule of thumb
Call Extend on the corresponding bridgeCall it directly with a Direct Reference
Use the same interact key whether it's a button or a signpostStandardize Interact with an Interface
Leave the post-opening reaction to display and audio handlersAnnounce the occurrence with a Dispatcher

Loose coupling makes it easier to add another listener later. In exchange, tracing registrations and implementations takes more effort. Start small mechanisms from direct calls, and split things out once you can see operations you want to share or reactions you want to delegate.

Which of Direct Reference, Interface, and Event Dispatcher to choose for each thing you want to do

Hands-On: raise a bridge with E and announce it opened

We build a mechanism where pressing E sends Interact to a designated button, the button raises its corresponding bridge, and "the bridge opened" appears on screen.

To confirm the three methods' connections, the bridge is just a plank that appears. Step-detection, an extending animation, and a dedicated HUD can be added after it works.

The bridge plank is invisible at the start, appears when E operates the button, and an opened message is shown

1. Build the bridge and button bodies

Use a Third Person Blueprint project. Choose None if there is a Variant option, and open the template's walkable level. With Actor as parent, create BP_Bridge and BP_FloorButton.

Add a Static Mesh to each and choose the engine's standard Cube. Enable Show Engine Content in the asset picker to select it from Engine's BasicShapes.

ActorMesh ScaleCollision Presets
BP_BridgeX=6, Y=2, Z=0.2BlockAll
BP_FloorButtonX=0.8, Y=0.8, Z=0.2BlockAll

Turn off Simulate Physics on both, then Compile and save. Place one of each in the level with Actor Rotation 0 and Scale 1. Both planks are 20 cm tall, so putting the Actor's center 10 cm above the floor surface puts the underside on the floor.

Start on flat ground and confirm the long plank appears. Place them so the plank and button are visible from the Play start position, and so the player does not overlap the plank.

2. Build the logic that raises the bridge

In BP_Bridge's Event Graph, connect these two in order from BeginPlay. Both have Target set to self.

Startup nodeSetting
Set Actor Hidden In GameNew Hidden: true
Set Actor Enable CollisionNew Actor Enable Collision: false

Now the starting state during Play is a plank that is invisible and can be walked through. Hiding and collision are separate settings, so we change both.

BP_Bridge's BeginPlay sets Hidden to true and Enable Collision to false

Add OnBridgeExtended under Event Dispatchers in My Blueprint, with no Inputs. Then create a Custom Event Extend and connect white exec lines in this order.

  1. DoOnce. Start Closed off, Reset unconnected.
  2. Set Actor Hidden In Game. New Hidden is false.
  3. Set Actor Enable Collision. New Actor Enable Collision is true.
  4. Call OnBridgeExtended. Drag the Dispatcher and choose "Call."

Target is self on both Sets and on the Call. DoOnce is a node that lets execution through only the first time. Putting it on the bridge means that even if Extend is called from another entry point, the opening is not announced repeatedly during the same play session.

Extend passes through DoOnce, shows the bridge, enables collision, then calls OnBridgeExtended

Compile and save. Nothing calls Extend from outside yet, so the plank staying invisible during Play is correct.

3. Give the button an entry point that accepts "Interact"

Create BPI_Interactable from "Blueprints → Blueprint Interface" in the Content Browser. Rename the first function to Interact, leave both Inputs and Outputs empty, then Compile and save. The Interface defines the operation name; the logic that drives the button goes on the receiver.

Open BP_FloorButton, add BPI_Interactable under Class Settings → Interfaces → Implemented Interfaces, and Compile. Right-click in the Event Graph and add the Interface's Event Interact.

Rather than writing your own Custom Event with the same name, place the event from the Interface you added. If you cannot find it, right-click Interact under Interfaces in My Blueprint and open the implementation. Since there is no return value here, it can be implemented as an event.

4. Have the button call its corresponding bridge directly

Create a TargetBridge variable on BP_FloorButton. Its type is an Object Reference to BP_Bridge, with Instance Editable on. It is a type pointing at the placed bridge instance, not a Class Reference.

From Event Interact, connect to an Is Valid that has white exec pins. Put Get TargetBridge into Input Object. Is Valid checks whether the referenced target exists and is still usable.

From Get TargetBridge's blue output, create a node calling Extend, and connect Is Valid's success output to its white exec input. Extend's Target is TargetBridge. The Is Not Valid side does nothing and ends.

From the button's Event Interact, checking the bridge reference and calling that bridge's Extend only when valid

After Compile and save, select the button placed in the level and set the corresponding BP_Bridge in Target Bridge under Details. Turning on Instance Editable alone does not fill in the target. Complete this assignment too.

That is the Direct Reference part. The button calls the specific Extend logic on the bridge you designated.

5. Register for the opening notification first

Select the placed bridge in the Outliner and open Blueprints → Open Level Blueprint. Right-click and choose "Create a reference to [bridge name]" to place a reference to the placed bridge.

From its blue output, create Bind Event to OnBridgeExtended. Target is this bridge. Connect Event BeginPlay to Bind's white exec input.

Drag from Bind's red Event pin and use "Add Custom Event for Dispatcher" to create ShowBridgeOpened. From that Custom Event's white output, connect a Print String with In String "The bridge opened" and Duration 10 seconds.

Bind is the registration; ShowBridgeOpened is the reaction when the notification arrives. Putting the Print String right after BeginPlay or Bind would display it before the bridge ever opens.

Registering ShowBridgeOpened on the placed bridge's OnBridgeExtended. The red line is event registration and the white line is execution order

6. Send a Message to the button from the E key

Create an Actor Object Reference variable CurrentTarget in the Level Blueprint. That is "the target being operated right now." Do not make it a specific button Class type.

Go back to the level, select the button, and place a reference to the placed button in the Level Blueprint the same way. Connect Set CurrentTarget to the earlier Bind's white output and pass the button reference as the value. This completes the notification registration and the target assignment at startup.

After Compile, right-click in the graph and add a keyboard E event.

  1. From E's Pressed, connect to an Is Valid with white exec pins.
  2. Put Get CurrentTarget into Input Object.
  3. From Get CurrentTarget's blue output, create Interact (Message) with the envelope icon.
  4. Connect Is Valid's success output to the Message's white exec input. Target is CurrentTarget.

The Is Not Valid side does nothing. Here we send the operation name defined in BPI_Interactable to a target of type Actor. There is no need for a Cast To BP_FloorButton in between.

From E's Pressed, checking whether CurrentTarget is valid and sending the Interact Message to it

7. Confirm the display and notification, then add another listener

Compile and save both Actors, the Interface, and the Level Blueprint, then Play. Click the game view and press E.

CheckExpected result
Before pressing EThe bridge plank is invisible and no opened message appears
Press E onceThe bridge appears, then "The bridge opened" is shown
Release and press againThe bridge stays up. No new opened message appears
Stop and Play againYou start over from the bridge not being up

If nothing happens, confirm input with a Print String right after E. Next check CurrentTarget, the button's Interface, and the TargetBridge assignment. If the bridge appears but no notification arrives, inspect Bind's white line, Target, and red Event connection, plus the bridge's Call.

Next, stop Play and add one more Bind Event to OnBridgeExtended to the Level Blueprint. Target it at the same bridge and sandwich it on the white exec line after the first Bind and before Set CurrentTarget.

From the new Bind's red Event pin, create another Custom Event RecordBridgeOpened and connect a Print String "Recorded: bridge opened" (Duration 10 seconds).

Play and press E again and two messages appear. You added a post-opening reaction without touching the bridge's Blueprint. Confirm by whether both lines appeared, not by their order on screen. Instead of saving an achievement, we simply Print to see that reception worked.

8. Send the same Interact to a different kind of target

Create BP_Sign with Actor as parent and add BPI_Interactable. Connect Event Interact to a Print String "Read the signpost" (Duration 10 seconds), Compile, save, and place it in the level. Add a marker Cube if you want something visible.

Change only the reference passed to Set CurrentTarget in the Level Blueprint to this placed BP_Sign. The E key's Message node stays as it is.

Play and press E, and this time the signpost's message appears and no bridge does. The same way of asking — Interact — invoked a different Class's reaction. Set CurrentTarget back to the button afterwards.

Sponsored

Bonus: Good to Know Up Front

Making a button you step on, or a bridge that extends

The E key here sends to a predetermined target so we can test communication. To aim at whatever is in front of you, pass the Actor hit by a Line Trace into the Message's Target.

For a pressure plate, confirm the player with a Box Collision Overlap and connect to the button's same activation logic. For configuring the detection volume, the hands-on opening a door with a trigger is a useful reference.

To extend the bridge gradually, change its position with a Timeline and Call OnBridgeExtended from Finished. Separating "it started moving" from "it opened" lets display and audio react at the right moment.

Cast is for confirming a target's type

Cast is a node that checks whether a reference can be treated as the specified Class. It does not find a new target or convert something into a different Actor.

When you want to use a feature only a specific Character has, casting and calling directly is useful. But for asking a button and a signpost to do the same operation, as here, we standardized the operation name with an Interface. How to choose is covered in detail in Interfaces and Casting.

Unbind when you want to stop receiving

When switching the UI's display target to a different bridge, Unbind your event from the old bridge's Dispatcher and Bind to the new one. There are situations where you no longer want the old notifications even though the sender is still alive.

Rather than memorizing "you must always unbind on destruction or you leak memory," decide whose notifications you want, and until when. Distinguish Unbind All, which also removes other listeners, from removing your own.

Shared state still needs reading and notification

Even after gathering the game-wide score into GameState or similar, the coordination where the UI reads the value or receives changes remains. "Deciding where something lives" and "how you communicate with it" are separate.

The same goes for your own Components: the entry point for reducing health can be a function while the change notification is a Dispatcher.

Summary

The input side here sent Interact to a chosen target. The button called the corresponding bridge's Extend directly, and the bridge announced that it opened to its registered listeners. The three methods carry different roles within the same mechanism.

In your own graphs, separating "do I want the target to do something" from "do I want to announce something happened" makes both the placement of logic and the references you need come into view. To dig into registering notifications, continue to Event Dispatcher; to add more shared operations, Blueprint Interface.

Further Reading

Unreal Engine Notes in this section98