I’m not quite sure what the best practice is here and I’m looking for some help / suggestions from others.
I’ve got multiple creature types which inherit from a character class. They can all perform various melee attacks.
When a character performs a melee attack, I want to play an animation which causes the character to swing. Right now, the “when” to attack is decided by a behavior tree task based on some conditions. When the behavior tree decides its time to perform a melee attack, it calls a function inside of the creature class to “start” the attack. The implementation of the attack start is done inside of the creature blueprint. I use an integer value to track the attacking state, like so:
smash attack states:
0 - inactive
1 - beginning
2 - apply damage to overlapping actors
3 - complete
So, let’s do a quick example to make it more clear. Suppose a character has an AOE attack (using a hammer) which smashes the ground and damages any characters within a collision sphere.
The behavior tree AI decides its a good time to perform the “smash” attack. So, we have to inform the animation blueprint that we want to play some sort of hammer smashing animation or something. The behavior tree informs the blueprint to change its smashing state from 0 to 1. The animation blueprint is polling this smashing state value so that it can transition into playing the appropriate animation. Within the animation, there is an anim notify event which fires the moment the hammer smashes the ground. At this moment, we want to apply damage to any actors within an AOE. So, the AnimBP calls an event within the character blueprint called “ApplySmashAttack”. This function applies damage to all victims in the area of effect. However, we’re not done yet! The animation has not completed! The character needs to return to its idle pose, but our behavior tree can’t ‘complete’ until this idle pose has been reached. Within the behavior tree task, I have a ‘tick’ event which continuously polls the state of the attacking state. Once the attacking state reaches “3”, the task will fire a “execute finished - success” event, which allows the behavior tree to exit out of the task node and proceed to the next behavior. But wait, how is this value set? Within the animation blueprint, I fire another notify event at the very end of the animation sequence which then sets the attacking state to “3”.
All of this seems really hackish and I’m looking for ideas on how to do this more cleanly. With my current design, animation blueprints and behavior tree tasks don’t talk directly to each other. They have to use the character blueprint as an intermediary to pass state information around. I was thinking I could use the blackboard as a viable alternative, but in principle, should an animation blueprint even know or care about blackboards? That seems a bit beyond the role of responsibility of things an animation blueprint should know or care about, right?
How does everyone else keep animations, blueprints and behavior tree tasks synchronized?