Why use event dispatchers vs interface when ED's need a hard reference?

So, as far as I know, binding to an event dispatcher requires a hard reference to the blueprint that calls it, while interfaces do not.
Why would you use event dispatchers? Are there any benefits against interfaces?

1 Like

They are not the same use case, at-all.

Dispatcher talks to many actors in one call. Problem is, you have to bind using a known type.

Interface is way of sending and receiving messages with actors without knowing anything about them.

1 Like

As above, they serve different purposes. Also:

This actor will spawn 2 new actors, bind them and then destroy itself:

Even though it’s gone, and so are the hards refs, the connection between those two dynamically spawned actors remains intact. You can’t do that with an Interface.


If you bind 100000 delegates, a single call would be incredibly performant. Were you to send 100000 interface calls instead, you would not be able to, most likely… not in the next 5s while everything has to come to stop. Interface calls are slowish, but the required loop iteration would be sluggish AF.

2 Likes

This makes it sound like I should use event dispatchers whenever possible, even when passing values from one BP to another, and only use interfaces when I have no choice.
Am I right on this?
If the goal could be achieved with either, what would you choose?

Interfaces every time. Hardly ever use ED’s. Here’s why (hunting around for old post)… EDIT: Can’t find it… Advanced-Search FILTER is so useful it defaults to a Twinmotion tag every time. :rofl:

Event-Dispatchers made more sense when they were more clearly named: Attach-To-Event nodes imho (think capturing events from dynamically spawned actors). Using ED’s everywhere can really clutter your code, and that often leads to more problems than they’re worth (bug hunting :wink: ). But hey, both options have their fans and detractors. That’s how its always been. :stuck_out_tongue_winking_eye:

100k actors: Interface calls vs Event-Dispatchers??? It’d be interesting to see some official stats on that. But don’t overthink this. If you have 100k active actors in the world, you’re going to have way more immediate challenges anyway (unless you’re using high-performance ECS). :wink:

2 Likes

Instant crash vs Instantaneous. :innocent: You must have tried running a long BP loop, surely? Test it yourself, takes a minute to set it up - or do have a look at what interface does under the hood.

Interfaces every time […] But hey, both options have their fans and detractors. That’s how its always been

This makes no sense whatsoever. You use all methods of comms made available to you, quite often combine them altogether.


This makes it sound like I should use event dispatchers whenever possible

Interface comms and EDs serve different purposes. You choose a tool for the job, you do not design a job around a set of tools. If you’re making an item inspection systems where you juggle unrelated classes, you will use an interface. If half the classes need to delegate something, you would add that, too.

You always needed a target for every interface call. ED is registered once, that’s it. And event binding can be removed run-time, too.

4 Likes

You mean if I have multiple copies of the same actor containing an interface call, in the level, it gets called every time as opposed to EDs?

Just to add a bit about the use of dispatchers: Observer pattern - Wikipedia

Was just musing before if there were any official stats. Why? Because as you know, there’s no one benchmark. To really mean anything, you need to test against PIE vs Packaged vs BP nativization vs C++ native (across 4.18 / 4.27 / 5.x on standardized hardware)… . But I hear what you’re saying. For RPG / RTS / MMO type games especially the difference could be costly. :thinking:

Just meant before there is some freedom / flexibility here. So while Interfaces / ED’s serve different purposes, there’s also overlap… So you do have some freedom ultimately. In that you can architect a game to lean on or more heavily rely on one versus the other if you so choose. :wink:

We’re comparing apples to oranges. They’re not comparable. It’s not that it gets called, for the interface to deliver a message, you must explicitly send it to every instance every time you want something done.

In most situations, you will have little choice but to use one over the other because that’s the job at hand.

I also do not agree with EDs being messy, on the contrary. As soon as you add multiple interfaces, you will immediately see the clutter since every call is now available for every class even though they do not implement it.

• use an interface when you do not know the class you’re dealing with. The player walks around and Kicks stuff. We do not know what they’re going to kick. A rock? A door? A bucket? Air? A chicken? We want those entities to react but I don’t want to build a crazy deep inheritance chain since Air has nothing in commmon with a Chicken. This is a great job for an interface.

• I know precisely what happens when Chickens get the boot - so I can set it up ahead of time and then never worry about it again. When kicked, any chicken will broadcast a distress call to the 12 city guards. That’s a job for an Event Dispatcher.

The best part is that chickens and guards do not need to know about each other’s existence.

The player kicks a chicken via an interface → chicken dispatches a distress call to everyone who was told to listen.

7 Likes

two options I use

  1. make your own event dispatcher using interfaces, ie you have an array of listening objects and send an event by interface to them.

  2. use an event component where you’ll have a hard ref to the component but since thats all it does it’ll be a super small footprint

  3. (i wish) allow interfaces to return event delegates? is this not possible?

All 12 guards must have a hard reference to the chicken though, right? Would this be more costly than interface? What would perform better?
I’m more worried about the hardware/performance cost than picking the wrong tool for the job.

No they don’t. That’s the whole point, they do not even need to know chickens exist.

And the interface is the slowest means of comms anyway. You can’t even compare it here.

2 Likes

Wait. From the Unreal documentation Event Dispatchers and Delegates Quick Start Guide in Unreal Engine | Unreal Engine 5.0 Documentation :

As far as I know, if checking in the reference viewer, you’ll see a hard reference to the calling blueprint. Am I missing something here?

Yes, the town actor will bind chickens & guards. They will never access one another via a reference. If you have a complex enough system, you’d have a managing class (a spawn manager) handle that kind of thing.

See the post above:


I use it with components a lot:

These 2 components can talk even though they do not reference one another.


Another undeniably cool feature of EDs is how neat can child-parent comms become:

Think of it as of autobind.

But, as @game-maker mentioned above, there is some overlap, and there will be scenarios more suitable to interface comms. If you’re building a truly modular system and do not know upfront what actor class the component will end up in - an interface would work more than fine instead, better.

2 Likes

You can use an intermediate actor or actor component or subsystem to break hard referencing if using event dispatches. For example make an actor component that attaches to game mode which just has all the event dispatches.

i do like 99% of my communication using event dispatches. Actually I don’t use interfaces at all because I haven’t found a need.

To me, event dispatch is a very future friendly way to handle communication because of the 1-to-many communication style. I can add new actors and just bind them to events, no worries. It makes for a pretty easy “fire and forget” system.

On a side note, i would caution new developers to not get carried away trying to avoid hard references and decoupling unless you can demonstrate why the hard-referencing is causing a problem in your project. You stand to complicate your code considerably and slow down development a lot for no good reason. Always make sure you can explain the concrete problem that actually exist in your project before committing time to making a solution for it.

5 Likes