How do I let an external blueprint know that an animation blueprint has reached a certain state?

Is there a method to perform the equivalent of an external callback from an animation blueprint?

I’m attempting to build a pretty basic gameplay animation pattern where external logic can know when the animation state machine is in a good state for various gameplay patterns to resume. For example, a ladder climb; when the player gets to the top, and plays an ‘exit ladder’ animation, I need to know when to resume locomotion, and, say, enable jump. Note that I am not literally implementing a ladder, but this is a good generic example.

Normally I would do this with a callback of some sort at the end of the ladder-exit animation, but so far in Unreal the only pattern I can find is to poll an animation blueprint value, and have various parts of the state machine update that value on the ABP.

I’m not fond of polling data from a tick function in order to check what state something is in. I know you can call functions on the owning actor from the event graph, but every place where I can know that I’ve exited a state or entered another is thread-safe, which means I have no ability to call into the event graph or access other actors.

A middle ground might be for the ABP’s event graph to poll itself in order to call functions on the owner, however, I don’t seem to have any way of querying the state machine of the ABP to determine which is active.

It seems to me that the only way to do this is to use an error-prone route of manually setting and clearing values, and then checking those.

Am I wrong?

1 Like

I think there’s an over complication going on here. Let me tell you about all the approaches that you might consider using to achieve your goal.

  • You should be able to cast to your animation blueprint by plugging the Get Anim Instance node that can be dragged out from a mesh into the object pin of the Cast To node. There might be other ways to achieve that objective without using the Cast To node, but I don’t think that would be necessary anyway. Because usually animation blueprints are made to execute animations in it’s anim graph according to the variables that are casted from the character blueprint. If that’s not the case, you would still be able to calculate the same values of the variables that you use as transition conditions or parameters in your animations by implementing the same logic in your character blueprint or any other blueprint. With that being said, you should already be able to know the current state of your animations, either being which state of a given locomotion they might be in or the values of the parameters that manipulate the animations themselves.
  • About your concerns on using the Event Tick, I can assure you that you won’t face any performance wise issues assuming all you wanna do is just checking a bunch of variables every frame. If you’re worried about that it won’t seem professional, I think it would be very unnecessary to attempt fancier implementations of the same thing considering how simple the task is. But you would be correct that it’s not the most efficient way to do it. Of course it wouldn’t be smart to check variables in the times when we know they can’t change values. For that reason, you could consider using event dispatchers.
  • As for my final suggestion, you could also use animation montages along with your locomotions for certain animations that don’t belong in the character’s usual mechanics. They are great to use in situations like climbing ladders, jumping over barriers, interacting with the surroundings, and more! And they would be certainly easier to add onto your existing locomotions, and also provide more practical ways to detect in which state of the animations they are. (Note that you would need to plug in a default slot into your main out pose of your anim graph in your animation blueprint in order to make anim montages work)

I hope I was able to clear up some confusions if there were any, and these suggestions can be helpful to you! :innocent:

None of those things are my issue, it’s simply that in my experience of decades of professional game development, expecting a bunch of variables to stay in sync across multiple systems is a guarantee of regressions. I much prefer picking systems which are robust and don’t require extra setup or maintenance.

Also, montages won’t work for the system I am building, as there are portions of it which need direct player control, which would require the montage itself to be manipulated while it was running. It is possible I am missing something about how to use montages, but they seemed to generally be unfriendly to branching logic.

I did find a general workaround which is that from a thread safe statemachine update call, I could set the current state name, and from the ABP’s tick check for changes against the last statemachine name, and then from there I can direct functions outward.

It’s just an awkward pattern when really all I need is a callback.

The ladder is probably ypur perfect example.

Instead of overcomplicating things, make an animBP with just ladder climb states - up/down, maybe slide down fast, take damage, maybe reload, and obviously enter/exit.

Then, at runtime you swap the animBP of the character so that the player cannot possibly do anything but what is allowed by the states of the ABP.

Your exit state will then have a callback, probably synced to the end animation, maybe by way of state transition notify, which happens to be the only type of Sure Fire notify, do look that up.

And the callback, or maybe even an interface implementation will swap the ABP back to the one where locomotion states exist.

Under no circumstance do you ever perform any logic or calculations withon an ABP, or its state transitions.

Everything should always be governd and managed directly by the character blueprint. And you do this by setting booleans whenever possible - to avoid having to use < or > comparisons in transitions.

Then, this approach doesn’t necessarily jive with combat, or really any action which is by nature interruptible.
For that, you create your own function with variying parameters that handles your own montages - generally you do so off an Input Buffer so that complex combos are possible.
The more complex the function handling the montages is, the more precise the end result usually gets.
This being main gameplay, you really shouldn’t bother too much with performance concerns so long as you follow best practice.

You never use notifies on a montage to handle anything.
But if you code for it, you can use animation curves and other things in the montage to have code run - the function handling the montage is generally capable of this since it is the one running before the montage even plays.

You will probably need to open up a c++ custom animation reading system to do more complex things like prediction, reading ahead by X frames in an animation, and other similar things which aren’t really a necessity for basic systems…

This is all useful information. Question though, you talk about “State Transition Notify” being a surefire notify. However, I can’t find any documentation about state transition notifies; mind pointing me in the right direction?

I’ve already built my stuff so that the ABP isn’t doing any logic of its own, so that part is good. I’m curious about swapping ABPs – wouldn’t swapping an ABP lead to animation popping/snapping since they wouldn’t be able to transition to each other? I’ve been looking at states to mitigate this but maybe there’s something I’m missing on that note.

Like, how would one have a ladder ABP and locomotion ABP and swap them so that the animation was continuous and unbroken?

The swap happens in less than a frame, so it is not normally noticeable provided the animation is somewhat similar (idle pose?).

The new docs really suck.
Within state machine transitions you can add notifies which are always called.

Thanks for that info.

I tend to not want to have to force animators into common poses for system swaps, so changing animation blueprints doesn’t seem like a great path forward for us. I would assume there’s probably some method of bridging the two if I wanted to dive into animation programming and build some custom single node anim instances to store the previous pose and blend to the new pose but I’m not much of a low level animation programmer and would like to avoid it.