I have an event set in a Level Blueprint that I would like to call from a widget after pressing a button. I have read the tutorial about dispatchers, but it is not very specific and didn’t provide me with answers. I created a reference blueprint and object, so I can see and call events from the widget to that object, and I can reference that object from the blueprint, but I still can’t reference Level Blueprint to run events from there. Can anyone provide me, with a simple, step-by-solution?
How do you get the actor with the widget (component?) into the world? Do you place it in the scene or do you spawn it dynamically - if so, which blueprint spawns that actor?
I place it in the scene.
Where you create the widget you can pull off of that and get your button, so if it is in the Controller, you get player controller, cast to your controller, convert to pure cast, call your character controller in the Level Map, and call the event from the widget through your controller. But there are easier ways to do this. The better way, is on the BP you want to trigger something from, casting in that and calling event directly from the created widget in the object. Less Cast = Less delay, and less hit on processors.
Avoid scripting in the LB unless you’re after some it happens in this level only thing. But perhaps you have an arch vis project and want to update the skylight with a widget slider. Meh.
Simple way to communicate between
Widget and level blueprint
&
I place it in the scene.
Assuming an actor in the LB has a widget component with a widget + a button:
Every time you click, the custom event fires in the LB.
And you can simplify the whole thing a bit if you encapsulate widget component → actor communication in the actor itself and fire your own dispatcher (which you may need anyway for the UI interaction).
The less LB knows, the better:
First of all make sure that you doing things right, level blueprint is intended to be used exclusively for level scripting and it only should have code to level you making, so if code you trickering is something that is used in multiple levels you should have that in game mode or other classes.
Level blueprint can’t have event due to technical difficulties to implement that, it’s blueprint class of ALevelScriptActor embedded with the level and UE4 spawns it’s actor (because level blueprint is actually a actor)
Each blueprint is a class on it’s own so with each level creates new class, as each level would be different class referencing that to other blueprint would be a pain as you would need to cast to different classes depenend on level and you can’t cast to diffrent classes dynamically making it impossible. You may think to create base class of ALevelScriptActor which you can actully do, but for some reason ALevelScriptActor is not blueprinttable, either for workflow or some technical reason. But again it;s’ doable in C++ and you can make C++ wrapper to reference level blueprint in other blueprints.
So yea only way to do it without touching C++ is event dispatchers, event dispatchers should be called in the widget, whole in level blueprint you do bind. In dispachers event caller don’t need any reference to classes objects to call the event somewhere else, this whole point of event dispatchers.
I didn’t notice that question, Yes I added this way
Those are screenshots of the Level Blueprint (I used Print String event for a test) and First Person Charcter creation of the widget.
-add event dispacher in class you want to call the event, it’s on table where you got varbale
-in class you want event to be called in you need to bind the event, and bind via special node (you find it via name of event dispatcher) from object that will do event call, in your case it’s a widget.
-In widget you do the event call also with special node, again you find it via event dispatcher name when you right click on empty space
I tried making shortcut and it didn’t work for exactly that reason. And yes, the Hello string is not displayed on the screen.
References reference instances, so it does not matter. You can bind to dispatcher at any moment you like and you can do this also by waiting for right moment in tick, or make separate delegate indicating readiness.
The Widget is created by the First Person Character, so the blueprint is there (not in the object). However when I reference it in this way (connections work, and it is compiling) nothing happens after I press the button.
I don’t know how tu use dispatchers in that way and tutorials are not helpful.
so the blueprint is there (not in the
object).
What does this mean? Are you using a widget component or Create Widget → Add to Viewport?
You never answered this bit.
nothing happens after I press the
button.
Can you show the script?
You can skip the cast in this case and just do:
FPC → Sleep Menu > Sleep Button → Bind
Now that we see how the widget is created, we’re trying to bind to a non-existing instance. So that will not work for sure.
@anonymous_user_f5a50610 - if you look at how he creates the widget (long after LB’s begin play), it’s pretty clear this will not work. Dispatchers bind to instances not to references.
Yeah, that makes sense. I really hope you have a good reason to do it this way.
- add an Event Dispatcher in the player and call it right after creating the widget:
Keep the rest of your script as is, it’s more than fine.
- the LB can catch it and bind the widget even more dynamically, so to speak:
If @anonymous_user_f5a50610 now bans me for posting this, it’s on you ;p
Alternatively, consider telling us what the end goal is. I’m 99.9% sure there’s a cleaner solution. What are we putting to sleep?
also by waiting for right moment in
tick
I’ve seen people do it. Is this something unavoidable? It surely is not good practice. Better than waiting for the latent system to kick in, probably. Still, sounds strange to Tick-query something just to see if it’s ready for a dynamic bind.
Maybe I’m overreacting. But it sounds like a small debugging nightmare waiting to happen.