Event Dispatchers explained - Finally!

Good work. I will be very thankful, if you can do some stuff about: “event RCP’s” and “switch has authority” nodes…

Ok, this is great but I don’t understand the point of the referencing bit.

For example,

I have a BP which spawns 1000 cubes. This BP will at some point initiate an event within each cube which ultimately will destroy each cube. At the moment, when I create the cubes i add them to an array, then I can perform a for each loop to trigger the event in each cube instance.

I just tried changing this array method to an event dispatcher method, it’s great in theory and will reduce the clutter in my BP, but why does there need to be a reference to my ‘spawning’ BP in my ‘cube’ bp (On the bind)? Shouldn’t it be able to bind without a reference, and just listen for the event dispatcher call?

finally I know what they are about!!! thanks a lot!!

Thanks, great explanation!

on small remark:

Shouldn’t that be saying?

Yes! Finally! Even this post being from February it took quite some time to find it.

Thank you good sir! You have done your community a great service.

Great explanations, DNADrone!

I have made a ticket to see if there is anything from your common sense examples that could be added into our docs. I think the WHY part is the most informative part of your post that is missing entirely from the docs.

My 2 cents on when interfaces make sense: You are going to do a repeated action over and over again that could benefit from some ‘data passing’ templates. A good example of this is from the bow and arrow template project we released, or the original bullet train demo. The Hands are each blueprints with an “interaction” interface and every time the hands overlap they send an interface message about a potential interaction, and the interface allows objects with the inteface implemented to pass back all the info the hands need to do whatever they may want to do (can they grab, where to grab, is it a 1 or 2 hand grab etc). Means to add more interactible object you just implement the interface and check some boxes (plus any custom logic obviously).

Is there a limit to how many event dispatchers a project can use?

A question:
In the example where I wish to control 100 lights with a single switch, how do i reference the switch to the lights?
What if there are 10 different switches and each controls all 100 lights? How do I set up the references?

I could do it with the “get all actor of class” But I heard I shouldn’t use it. what are my other options?

Whats the purpose of Event Dispatchers?

Whats the difference in using Interfaces? In Both cases I need to reference the Dispatcher/Event-Blueprint.

that moment when what you just explained is clearer than UE4’s documentation. SOMEBODY HIRE THIS GOD!

You shouldn’t SPAM it. It’s ok (even mandatory at times) to use it, it’s just not ok to use it all the time, everywhere and anywhere (i.e. on Tick, as the description states).

Assuming all 100 lights are of the same type and all the switches are of the same type:

In the light script, you use BeginPlay->GetAllActorsOfClass(YourSwitchClass)->ForEachLoop->BindEventOnWhateverDispatcher->ToggleLight. (You pass your condition via that dispatcher, for example, a ‘range’ parameter. Let’s say you want a light to be toggled only when a switch which is within a particular range of it is activated. If you don’t have a condition, all the lights would toggle upon the activation of any switch.)

In the switch script, things are simpler: create a custom event, say OnInteractedWith->CallEventWhateverDispacher.

The switch has no reference to the light and the light has only one reference to the switch, meaning they are almost completely independent and project-agnostic (I could copy-paste your switch and I wouldn’t get a single error. I would simply need to create my own light).

Interfaces, on the other hand, create references, as they are tied to a particular class. Copy-pasting wouldn’t be as easy. Modularity is somewhat broken by comparison with EventDispachers.

Hope this helps!
@

When used properly, I don’t see a functional difference. Let’s say you fire a projectile, and you want that projectile to “do something” to an object it hits:

OnHit>CastToJoeActor>AsJoeActor>InterfaceCall

This works great, assuming everything you want to hit is JoeActor or a subclass of JoeActor. Interface message to the rescue!

OnHit>InterfaceCall(Message)

This will send a class-agnostic “message” to WHATEVER you hit. If that thing you hit has the interface you referenced, it will call it. If not, it will just not fire. (Like casting.) This is handy when you have players, enemies, and props with different classes. As long as those classes have the interface, they should respond to the interface message sent by the OnHit.

1 Like

@

One possible solution: Perform a single “get all actor of class” and add them all to an array. The next time you want to send them all something, just cycle through said array. If you need to procedurally add lights, make sure adding the resultant actor to the aforementioned array is part of the procedure.

I’m sorry for necroing this thread, but I felt the need to add something to it, with the hope of getting answers.

I actually do not see the point in those Event Dispatchers. The only thing they have going for them opposed to normal events are that they are a collection of events. You save yourself a few nodes but that is it.
I’m relatively new to UE4, but what I’m currently missing as a feature is static event dispatchers.
Currently, every listening object needs (!) a reference to the object that owns the dispatcher.

If I have, for example, a StatsComponent which has HP and an OnHit Event Dispatcher, I can link HP loss and the dispatcher just fine, but what if I wanted to have another component that does something else when the OnHit dispatcher is called? For example, change the camera settings. I can not just put a node in “OnHitEvent” which then changes the camera settings; I need a reference to a StatsComponent first. In LibGDX, a java code-based game engine, this worked just fine; I would call the OnHit Event (dispatcher in this case) and any system that wanted to have some input once OnHit gets called could just register itself as a listener, without the need to “know” of an object first. The actors which were then manipulated by the event were then given as parameters.

To give an example of the workflow I want to have in UE4:
I have an event dispatcher called “Get Hit” in my StatsComponent. This dispatcher has several inputs: ActorA, ActorB, and damage. ActorA is the attacker, ActorB the attacked.
Inside the StatsComponent I bind an event to this Get Hit dispatcher to actually deal with the damage.
Later on, I decide I need to add more flashiness when someone gets hit. I want to show a blood splatter on my HUD. But since I want my code/bp to be organized and tidy, I want to handle this in a different blueprint. Otherwise, I would have to reference my HUD object inside my StatsComponent to activate this blood splatter. This isn’t good style, as the whole thing could become very messy very fast, as there is a lot of functionality you could theoretically handle. Camera effects like screen shake, sounds, particle effects, material instance parameter changes and so on. You don’t want those in your StatsComponent.
Rather, you want to just catch this OnHit event and be given all the things you need to know about.
So, I want to go to my HUD blueprint and make a node “OnHitEvent”, which is a node that gets triggered once the OnHit dispatcher gets called. If I need to know who was hit by whom, this event can just have the necessary inputs, so you can plug in whom is damaged by whom instead of you needing a reference to some object that has a StatsComponent. How would I get this component in, for example, a SoundComponent that is supposed to handle different sounds under different scenarios?

Is there something I’m not getting or does UE4 simply not have this kind of functionality (yet)? It seems counterintuitive that we can bind events to dispatchers, when we, in the end, still need to reference the object owning the dispatcher in each and every single case. You could just call a normal event then. Is there some kind of functionality that I don’t know of that can replicate the behavior I described above?

EDIT:
To precisely say where the fault lies: it’s the target node when binding an event. If we didn’t need that and instead could just call it statically, we could easily add functionality without bloating up single blueprints with content where it doesn’t belong to.
I could go to my SoundComponent and bind the “PlaySound” event to the “OnHit” Event Dispatcher without having to know about WHICH object’s OnHit Dispatcher I’m calling. You could transfer the target to a parameter. This way, you could just use “self” as a parameter if you had to know about the blueprint the dispatcher is owned by.

2 Likes

Dispatchers work very well with blueprintable components.
For eg in game state blueprint you create dispatcher to turn of/off lights.
Then you create blueprintable component that hooks to it, and turns lights in owner actor.
This way you can have great system for managing lights without repeating same code in all possible actors that may need light.

What you’ve described is pretty much how UR4 works, so I’m confused about why you’re confused. I think you need to study the collision mechanism more closely.

This:

has been absolutely worth its weight in gold to me. I mean, that’s not right because it’s just a bunch of bits on a webserver somewhere; more like it’s worth a lot, I guess. :slight_smile:

As far as event dispatchers go, I don’t think you’ve quite got it. Event dispatchers aren’t (usually) used for one-to-one events (e.g., pawn->controller->hud) but for one-to-many, many-to-one and many-to-many events.

For example, suppose you had a game in which there were two teams.

Without event dispatchers: Each member of a team might have an array of pawns (or controllers) to keep track of their teammates (or, more likely all players). When a member of team gets in trouble (e.g., taking fire, needs healing, etc.) you would loop through the teammate array calling an event on each same-team pawn (or controller) to indicate to the team to help (the HelpMe event). This is pretty complicated and doesn’t scale very well. Each player has an array of pawns/controllers, has their own for loop, etc. Now it’s not terrible, but suppose you had 20 such events. Yuck. Now suppose one of those players dies. You need to do one of two things: either ignore the dead player (your for loop now has a new conditional) or you remove the player from each array “owned” by the player by calling yet another event on each pawn/controller (“PlayerDied”).

With event dispatchers: On pawn/controller BeginPlay you bind to globally available event dispatchers to receive the HelpMe, and whatever other events you need to receive globally (you probably don’t actually need a PlayerDied event). The HelpMe event has as a parameter the player/controller to indicate who needs help. If the player/controller is on your team you respond one way and otherwise ignore it (or whatever). When a player dies you unbind all events from that player/controller.

So, with event dispatchers there’s no looping, no arrays, nothing to keep track of other than THIS player. You can certainly keep track of other things if you need to, but with event dispatchers, it’s not required in the same ways as without them. One way you can think about it is that the event dispatchers keep track of the arrays and performs the loops you would.

Event dispatchers tend to make your code/BP cleaner and more concise and keep your class variables less cluttered (the event dispatchers will tell you who/what “needs the thing”, rather than you iterating through a list to figure it out).

Thank you so much! I was able to solve a problem that I was having with a menu system with this.
https://forums.unrealengine.com/showthread.php?149231-Blueprint-Communication-Issue&p=732613&viewfull=1#post732613

Maybe I missed this in the post but how do you unbind only one object bond to a dispatcher? Example I have four different actors bound to an event but after a condition only one of the four will stop listening the other three are still listening
The “unbind event from” asks for an event which doesn’t makes sense if all I want to do is unbind it I thought the event was if an unbind all was called but I can’t get it to fire. The unbind all, unbinds everything which I don’t want…

Great post, it’s helpful , I am looking forward something about explaining event dispatcher. This post should be studied carefully.

Hi DNADrone, i had the very same question. Now i use event dispatchers a lot…so useful. Still have to learn BP Interfaces :slight_smile: