BlendSpace animation transitions look wrong

Godot Version

4.6.beta3

Question

I’m just starting out trying to get a character moving through idle>walk>run>sprint in an animation tree. Code is working great, everything triggers, joystick weight responsive, etc. My issue is with the blending of animations. Whatever I try I see to have this issue when the input value is somewhere between the animation nodes, performing a blend where it just looks wrong, legs or arms go out of sync, character looks like they’re going to trip over themself, which then straightens out once the input weight is clearly in favour of the next animation node.

I’ve used some Mixamo animations but also tried Quaternious UAL and having the same issues. I’ve also bone-mapped to a general Godot skeleton and even tried retiming the animations in Blender to a matched/normalised 35 fps (based on the walk).

The individual animations loop and look fine. These are all in-place animations being moved with physics - they have a root bone, but it is static in the animations. I’ve tried both assigning and ignore the root motion node in the animation tree.

I have Sync enabled on the tree and verified the phasing on the animations (same foot at start, same other foot halfway through, and back). I’ve now started trying to play with the Custom Timeline but this seems to make no difference. I’m attaching a short screenshot of the blending, this is on two animations from blender, bone-mapped but otherwise untouched:

  • Walk is 35 frames long, 1.16 seconds at 30fps, right foot down first
  • Sprint is 21 frames long, 0.7 seconds at 30fps, right foot down first

I’ve made a short video here: BlendSpace animation transitions look wrong

Any thoughts most appreciated, I’m sure this is just newbie issues.

Thanks
David

I think it might be a problem on synch between animations. Even if the first/middle/end are correct, the timing might be wrong ?

T=0 T=X T=Y
walk right food down left foot down ???
run right food down ??? left foot down

From what I understand, the mixer just gives you a lerp between the two animations, weighted by the value.

If my theory is correct, this should not happen if you normalize the animations, such that they are not only the same amount of frames, but also the same time length.

There were issues about this a while back, tho it should be fixed :thinking:

Added AnimationSyncNode with the sync option as a base class and made any AnimationNode that may branch in the AnimationTree inherit from it.

Thus, AnimationTransitionNode is now has sync.
However, if the animation is played from the beginning after switching state, sync will be broken.

To prevent this, the option from_start is added in AnimationTransitionNode.
Also, BlendSpace1D/2D now has sync. This allows animations in multiple directions to be blended without breaking sync.

So I’m guessing messing with the AnimationNodeTransition settings might fix your issue

Enabling the sync property just makes the animation that is blending continue to play even when the blend value is 0. The transition looks bad because even though both animations start with the right foot down the left foot doesn’t touch the ground on the same frame in both animations. And your animation aren’t the same length so the run animation will start over from the beginning before the walk animation. Basically, your animations are out of sync because they are not the same length.

Both of your AnimationNodeAnimations need to connect to a AnimationNodeTimeScale and then the AnimationNodeAnimations connect to the AnimationNodeBlend2.

Then use AnimationNodeTimeScale to scale your animations so that they’re always the same length. As your blend value increases you’ll need to update the amount both animations are scaled. When your blend value is 0 your walk animation should not be scaled at all and your run animation should be scaled to 1.16 seconds. Like wise when your blend value is 1 your walk animation should be scaled to 0.7 seconds and your run animation should not be scaled at all. When your blend value is somewhere between 0 and 1 you’ll need to scale the time of both animations linearly keeping the animation the same length. For example when your blend value is 0.5 both animations should be scaled so that their lengths are 0.93.

Many thanks for both your responses - its helped clarify thinking for me, much appreciated.

I now have this working much better- firstly it had not occurred to me I could drop a blendtree inside a blendspace even though its right there in the dropdown, doh. Secondly a little godot glitch in the tree means sometimes scrubbing up and down a blendspace still shows the muddled blend but if you play the game its nowhere near as bad. I think generally its restarting the project in godot whenever a bunch of timescales are adjusted in the tree?

Anyway I’ve ended up with this:

StateMachine

  • BlendSpace1D (Locomotion)
    • Node1: Animation (Idle)
    • Node2: BlendTree (Walk)
      • TimeScale: 1.67 (Walk 1.16 / Run 0.7)
    • Node3: BlendTree (Run)
      • TimeScale: 1.36 (Run 0.7 / Sprint 0.51)
    • Node4: Animation (Sprint)

No additional code required, everything ran off the existing input. There’s still a little bit of wonkiness in the mix but its quite minor and suspect at this point its in the detail of the animations. Maybe something to tweak in Blender and reimport? Do let me know if you think I shouldn’t be stacking up blendtree’s like that in the blendspace.

Again, thanks for your help.

David