Most efficient way to check an arbitrary animBP's vars?

Situation:
I have a Character BP and in its construction script I set the skeletal mesh for it. In the Character BP’s event graph, on Begin Play I set the corresponding animation blueprint for the skeletal mesh via Set Anim Instance Class.

(The variables in each of the viable character anim blueprints are exactly the same. The only difference is the actual animations in the state machine.)

Goal:
To check and set variables in the animation blueprint from the Character BP event graph.

Problem:
Assuming the only way to get access to variables inside an anim blueprint is by casting to the correct Anim BP from Get Anim Instance on the mesh, that means I have to do a check for which anim BP to check/change every single time I want to interface with it. seems bad because even though I know exactly what Anim BP to check right at Begin Play, I have to do the same check for what Anim BP every time I want to check or change variables in it.

Question:
In the case where the animation blueprint to check is unknown until the level loads, what’s the most efficient way to change and check variables (sometimes every frame) in an animation blueprint?

Thanks!

I have not dealt with animations yet. However, I might be able to guide you in the right direction. Also, screenshots of your blueprints would help understand what you are trying to achieve.

Solution #1

In your Character BP during BeginPlay, can you take your Anim BP that is returned by Get Anim Instance on the mesh and cast it to your Animation BP and store that in a class variable inside of Character BP? That way casting only happens once – during BeginPlay (or perhaps you can move to the ConstructionScript).

All subsequent calls to the Animation BP that changes values within it would reference the class variable that has a type of the Animation BP that you need to reference.

Solution #2
If you have two different Animation BPs, let’s say ABP_Animation1 and ABP_Animation2 and both of these have the same variables exposed then you might want to look into leveraging a Blueprint Interface. Create a BP interface that both ABP_Animation1 and ABP_Animation2 implement and create one or more methods that will Set/Get your variable(s) that are common among the animations.

way in your Character BP’s BeginPlay/Construction script instead of casting to an Animation BP you can cast it to a Blueprint Interface. That way, it doesn’t matter if the Character BP class variable has an instance of ABP_Animation1 or ABP_Animation2, as long as the object instance implements the interface that matches the class variable type you are good to go.

Hey, elitereloaded!
Thanks a lot for the help. I can provide screenshots, but it’s going to be a lot. hehe

Solution #1
Yes, in Begin Play I can Get Anim Instance and cast it to my Anim BP. But the problem with that is that there are 2 possible Anim BPs. I can do the check there and set the appropriate one, but when I actually want to query or set variables in that Anim BP, I still have to do the same check again to see which one I need to query or set variables of.

Solution #2
I tried using a blueprint interface. It’s my first time with them so I’m probably not using it correctly. (I’m pretty used to using event dispatchers, but BPIs are still a bit mysterious to me.)

I’ll up some pics of my attempt at implementing Solution #2.

Thanks again!

Think of interfaces as a public agreement. Any Actor or Object that implements an interface is guaranteeing that it implements the methods (aka signatures) that are in it.

Therefore during the development of code you start to realize that parts of your code only cares about certain functionality. These parts of code could be refactored/implement so instead of them accepting an actual concrete type blueprint class like MyFlowerBP or MySwordBP it accepts an interface.

Here are some practical examples taken out of my own game I’ve been working on.

I have an interface BPI_GameClock and the sole responsibility of the interface is to provide publicly accessible functions that return information about my game’s clock. I.e. what the hour/minute/month/day/year is.

Now currently my GameState (BP_GameState) implements interface.

I have a slate Widget called WB_GameClock and… You got it, it’s sole responsibility is to display the game clock – Widget doesn’t give two hoots about how the GameClock functions. The Widget doesn’t care if the game speed was increased therefore increasing the speed of the clock. The WB_GameClock ONLY cares about displaying the clock. Likewise, the GameState doesn’t care about how to display the game clock because that responsibility is up to the Widget.

So to achieve single responsibility isolation I use the interface BPI_GameClock that I created.

My BP_GameState implements BPI_GameClock.

My WB_GameClock Widget has an Exposed On Spawn variable called “GameClock” and it’s variable type is BPI_GameClock.

My PlayerController spawns the WB_GameClock and sets the “GameClock” spawn variable to an instance of my GameState that has been casted to BPI_GameClock.

So with my understanding of your situation it sounds like an interface is the perfect solution.

If you can provide me the names of your Animation Blueprints and the variables you are getting/setting that would help me with helping you better.

Another practical example that might help you understand.

I have an interface called BPI_Actor_Selectable.

Any Actors spawned into my world that implements BPI_Actor_Selectable can be “Selected” by the player’s mouse. (“Selectable” is not necessarily “interactable”)

So in my PlayerController, on left mouse click when I iterate an array of Actor instances that are selected I filter the list of selected actors by removing Actors that do not implement BPI_Actor_Selectable.

Expose On Spawn allows you to set a Blueprint class variable when the Blueprint is “spawned” into the world or created. allows the variable that is being exposed to be available (and set) in time for the ConstructionScript and therefore before the BeginPlay event is triggered.

For example, look at my BP_MyActor blueprint below. One of the class variables are set to Editable (makes it editable outside of the Blueprint) and Expose on Spawn (allows the variable to be set when spawning/creating the object).

Below I am spawning the BP_MyActor and notice how it allows me to set my custom class variable that is Editable and Exposed On Spawn. That allows some powerful encapsulated design practices.

118581-screenshot_121316_073302_pm.jpg

Thank you very much for giving me those examples. That helps a lot. I’ve seen other tutorials about BPIs where people state what they do, but none of them are as clear as what you provided. Thanks! I’ll have to read over the last part of your first example a couple more times to understand the flow as there are some terms in there, specifically “Exposed On Spawn”, I’m not familiar with.

Anywho, here are some screenshots of the the two anim BPs in question, and the Char BP that they will interface with (there are about 6 other places in the char BP where I’m calling those 2 interface functions).

Anim BPs

CharBP

Thanks a ton for your time, elitereloaded!

Sorry to make you do that. I fully understand now, thanks. I’ve yet to use Expose on Spawn, though I frequently make vars editable/public. Thanks!

By all means let me know if you need any more screenshots. Afaik I’ve supplied the most pertinent ones.

I’m a bit familiar. Cool, that makes sense. The naming totally threw me off. hehe Thanks for the analogy!

Awesome, I never knew I could cast to the BPI off the anim instance. Apologies for failing to up the interface I made. I’m going to mark as the answer. If I run into a problem, I’ll update it today. But I’m pretty certain you’ve understood my problem and supplied me with the appropriate solution. Many thanks for all your help!

Yeah, I’ve read here and there that no errors are thrown when trying to call BPI functions that don’t exist. Thanks for the tip.

I have a slight problem though. I tried to drag off mesh > Get Anim Instance (within the Char BP), but the BPI (in my case, BPI_Boostable) wasn’t showing up. I’ve verified that it is in fact implemented in both the Human_Male/Female_AnimBP.

Ok so the variables you are trying to set for each animation is related to Boosting/Sprinting/Running.

Therefore, you could create a BPI_Anim_Boostable interface with 3 functions. StartBoost, StopBoost and IsBoosting. You could even create an interface function called “BoostTimespan” that will take a float parameter and execute the “boost” animation for that amount of seconds if you think you will use that functionality.

Implement your BPI_Anim_Boostable in both of your animation blueprints by going to the top of the editor and selected Class Settings menu and then on the right side under interfaces you can implement interfaces.

Interface functions that don’t return a value are treated as “Messages” or “Events” so you have to right click the event graph of the Actor that implements the interface and search for the name. See below.

In your Character BP you can now cast the animation to the BPI_Anim_Boostable interface type instead of worrying if the object is a Human_Male_AnimBP or Human_Female_AnimBP. After you make the cast the casted value will always have the functions that’s been defined in the interface. (I used the 3rd person character for )

Expose on Spawn is a very handy feature. If you’re familiar with other programming languages it’s similar to class Constructor parameters.

It’s UE4’s terminology, not sure why they didn’t call it “Make Constructor Parameter” or something like that.

Glad to help. Don’t forget to properly hook up the Cast Failed execution pin and log it for development debugging reasons.

As long as an object instance implements an interface you can cast it to that interface and it will succeed with the cast.

Oh, that’s interesting. I had to cast the BPI out in the open and then plug the anim instance into it. Strange it doesn’t appear when pulling off the anim instance. I’ve seen stranger though, hehe. Thanks!

Edit: Works real sweet like. Was able to set the cast to BPI to a BPI variable that I can pop off anywhere. Thanks for all the info, elitereloaded. I learned a lot!