Reputation: 20141
I have a number of animation sequences connected to an ENUM Blend Pose node. I can manually switch this enum value in the Anim Preview panel.
Now I wish to control this enum value from a bunch of buttons added to a User Widget. The widget is instantiated within the Level BP.
When I edit the onClick events on the buttons, I do not know how to get a reference to my enum variable (which I have exposed as Public in the Anim Blueprint's settings).
Essentially, each button is designed to change this variable to a unique value, which then should cause the appropriate animation to play within the Blend Pose.
How do I let the Widget have access to that variable? Or vice versa, how could I create a variable on the blueprint that can be used to set the Enum value on the Blend Pose?
Please note that I am using the visual blueprint editor, not C++ at this time.
Upvotes: 0
Views: 586
Reputation: 20141
Building on @MaxPlay's answer, here's my final (possibly sub-optimal) solution with images for posterity. I'll probably stumble upon this answer in a few years like I do with some of my other SO posts from years ago ;)
First, the Anim BP on my Actor (note that this is not the player's pawn but just another mesh in the world) which just sets up the Blend Poses, using an Enum.
It's really vitally important here to make sure the variable that holds the Enum is made public. You do that by clicking the eye icon next to the variable name. If you don't do this, no external class (blueprint) gets to read or set the value of that variable.
This is a screen grab of the variables portion of the Anim BP's properties panel.
And here's that Enum, which you can create as a blueprint. I've used it to have a nice textual reference that has semantic meaning. Also makes it easier to link to the buttons later.
Now we get into the heart of the matter - the Actor Blueprint. I just wrapped this blueprint around my Skeletal Mesh Asset by selecting it in the viewport and then using the Blueprint menu to convert it.
In the image below you can see the Details panel of that Actor Blueprint, showing how it composes the Anim BP
Next is the magic step!
I created a function on the Actor Blueprint that other blueprints can call with 1 parameter - the ENUM that I defined earlier. The goal of this function is as a public setter on the Anim BP's public variable. I wasn't able to expose this public variable outside the hierarchy, so this gets around that visibility issue by delegating the responsibility for setting the Anim BP's variable to its Actor BP.
Since the Actor Blueprint has a reference internally to its Skeletal Mesh's currently assigned animation blueprint, and that Anim BP's variable has been made public, it gets to set it directly.
The goal is to pass a reference to this Actor BP to the Widget so the Widget's buttons can call this method (function) at a later time.
Over on the Widget side, I'm exposing a variable, cast as that specific animation blueprint (so that the Widget knows about the SetAnimFromEnum
method). I'll be setting that variable in a moment.
Before I do, here's how the Widget Blueprint is set up - very simply, each button calls the same SetAnimFromEnum()
method and just passes a different value from the enum.
If you had a million buttons, this would not be efficient and you might want to invest in a bit more complex blueprinting (I'm not yet at that level) - ideas here are to somehow parse the name / label of the button and derive the appropriate enum from it, or revert to an integer-based Blend Pose node and add a property to each button, etc.
And finally, the glue that holds it all together: the Actor Blueprint that instantiates the widget. This is the part I don't like in my solution - in my mind, the widget shouldn't be so tightly coupled (composed) with the Actor BP. But I would have had to jump through more hoops if using the Global GameMode or GameState Blueprints, and this is just a proof-of-concept so I'm keeping it simple, if slightly messy.
The Animation Blueprint below shows me instantiating the Widget and using the return value to both add it to the Viewport, as well as then accessing the widget's public variable designed to hold a reference to this Actor Blueprint and setting it. That creates the link between these two blueprints allowing the Widget to then call a method on the Actor.
Upvotes: 1
Reputation: 4037
I am coming from a 100% C++ background, so I may have some options on my mind that are not entirely working in BP, but we'll get to that.
This is one simple way I can think of. You could also work with an event dispatcher that broadcasts whenever a button is pressed and your actor is subscribed to it to get notified.
I hope any of this helps.
Upvotes: 1