Using Event Dispatchers to communicate variable between blueprints

I am very new to UE4 and I’ve been trying to use the same variable in a widget blueprint and an actor blueprint. There is a cube that has its dimensions constantly changing, and I want the player to be able to go to a certain location and input a number where they’re able to change the rate at which the cube is changing. The cube changes, and the player is able to input a number, but nothing seems to actually change. I don’t know what’s going wrong as I’m pretty confused on just using event dispatchers in general. This is what I have:

Cube Blueprint:

Player Input Screen Blueprint:

Your “binding” isn’t hooked up to anything so that event “Play rate listener” is never actually activated to do anything. You need to have a sequence off your “begin play” and hook one of the execution pins into the “bind event” input execution pin.

Okay, I have the event hooked up now but it still doesn’t seem to change.

Event Dispatcher is essentially “Delegate” in C++ term.

Assigning (Link phase)

  1. The event binding must be connected (It is not wired in your graph, hence not bound)
  2. Parameters on the event dispatcher must be matching with the event parameters.
  3. It is best to bind the same event once.
  4. You can also unbind it at will, specified by event red square pin.
  5. You can bind multiple events at different places. When “Call Event” is executed, all event bounded will fire.
  6. Binding/Unbind a delegate doesn’t mean it firing the event when you bind it. Unless you call it right after.


If any case if the naming was bugged out, please click on the event dispatcher, on details panel, click copy signature and find the one with following name XX_DelegateSignature. (Copy with itself again to force an update)


Actually Executing

  • Whenever you want the red event that event dispatcher bound to execute, just “Call it”.
  • You must send values in, even if the value was a dummy.


Suggestion

  • Assuming the new graph of yours still similar to what I see, you should link the “bind event to” node in begin play, event timeline node.

Okay I think I binded it like you said, but the rate of the timeline isn’t changing.

You still lack a “Call PlayRate Event” node somewhere else.

I made a new actor blueprint setup like you did and use input node to toggle play rate. Timeline node was 10s long to print its own play rate value. Input node was placed in level blueprint so I can grab the references of “test” actor easily. I also run the game and test with instance selected in level. Hopefully, this would help.

(1.0 & 0.2 is not obvious. Use 1.0 and 0.01 instead.)
(The name of the test and the test2 actor refer to the same thing because I was first posted without throughout testing)

243888-callevent.png

My Call PlayRate event is still the same as it was in the second screenshot, but it doesn’t seem to call at all. I tested everything with Print String like you did and it seems that the cube doesn’t get the call in the first place. Do I have the target set wrong? Yours has “from Persistent Level” below it, but mine doesn’t. To get mine I made a variable and set the type to “Cube Blueprint” but I’m not sure if that’s the correct way of doing it.

  1. To ensure input is not accidentally consumed by Input-Enabled Actor and Player Controller, attach print string node to ensure input actually fired. (Input | Unreal Engine Documentation)

  2. My target is from persistent level because it was a quick prototype by spawning it into the level and use level blueprint to control it. You need to get your instance of the cube (Like spawn it somewhere and use GetAllActors to fetch it. If that instance is never existed, nothing will be called.

  3. Attach more print string to each of the called function to visually reflect what is being called and which is not, on top of real time simulation graph highlight. I may need to know how you spawn the cube thingy for further assist.

This is what I tested (Green - Printed; Red - NOT Printed):

  1. Will need to check the event dispatcher signature on the declaration. You might need to recopy the signature again by picking itself from the delegate list. If it existed, it might not be properly bound in the first place (4.17-4.18, 4.19 doesn’t have this issue)

  2. If it still doesn’t fix it, is there any way to get that blueprint to test locally? (Require setup and such)

I am using 4.19.2
I’m not sure what you mean by test locally

It means do you have the project somewhere to download/access and have people look into it?

What would be the best way to do that?

Use dropbox for this if project size is still affordable?

Does this link work okay?

Hello, I have received and take a look at your project.

It appears to me that you had set up the event call inside of a widget blueprint called “PlayerInputConsole”. However, this widget blueprint didn’t appear anywhere as it doesn’t spawn.

As your event relies on a text committed, but since I am unable to type anything anywhere, it will never be called.

So, I added BeginPlay inside of SideScrollerCharacter, and manually CreateWidget and add to the viewport.

Then, the UI you had set up has several issues:

  1. Font size was 238 without wrapped in scalebox (Why?)
  2. It covers the whole screen, so technically, it blocked everything.
  3. So I hide everything and rescale it back to a corner to test.
  4. But upon commit, you destroyed this widget.

Yes, the event indeed called, but your variable “Cube_Blueprint” is nullptr.
Calling an event on nullptr, nothing will happen. So the node didn’t fire.

and this method to send input only used once…(Why?)


To fix:

  1. You might not want to do it in the widget. Inputs aren’t received in widget unless forwarded from the controller. If you had to do in the widget, consider using SetVisibility to “HitTestSelfInvisible” rather than “Remove from viewport”.

  2. You need to fetch the world object in your widget using Set node. By default, they are nullptr if you just declare a type of “Cube_Blueprint”. You probably need the character to do a “GetActorOfAllClass” for now, and get the type of the object you want, and get the first one outta that array. Then, store a cache in your character blueprint. Then, go into the widget, use “GetOwningPlayerPawn”, cast to SideScrollerCharacter, then drag the pin from it to get the cached variable. By doing this, you are forwarding the cube object from the world → character → widget.

Hope this explanation would help.

Thank you so much! It all works now! I really appreciate your patience in helping me, thank you!