Character jumps after animation ends

Hello :wave:

I’m currently trying to make “directed animations” work for a game. By “directed animations” (is there a proper term for it?) I mean animations where the character has a different starting and ending position. Searched for it (with a couple of different terms and keywords), skimmed through everything animation-related in the docs – couldn’t find anything.

Think of a forward leap … or a sword attack combo (like this one on Mixamo … also used in the playground below).

My problem:

  • mixamo has no option for doing this animation “in place”. And since the movement is very non-linear, I feel it wouldn’t be a good choice anyways
  • after the animation is done, the character jumps back to the initial position. I would instead like him to be exactly at the animation end position

Playground:

After a moment of standing, an “in place” walking animation starts, and the character is moved by adjusting his position.z. Then, the sword combo starts. Each time it finishes, the character is set to his initial position again.

My questions:

  • how can I keep the mesh position in synch with the animation position?

    • I tried calling .getAbsolutePosition() on the “Hips” bone before starting the animation, and then inside the animation end observable, adding the delta to the character mesh. Didn’t work.
  • should I also apply that approach (letting the animation determine the character position) to the walking animation? I assume:

    • it would look more natural than the current, fully linear movement
    • it wouldn’t require having to “guess” a proper walking speed that somewhat matches the animation
    • it would require more computation than simply adding a fixed value to the mesh position, but probably in a neglectable order of magnitude

(not related to the question, but the playground itself)

  • why does to floor look so odd?

Thanks a lot already for any insights here :pray:

If you set the loop mode to relative for the sword animations then your character will walk along the ground instead of reseting its position each loop. And the other flickering issue is because createDefaultEnvironment is creating a ground at the same position as the one you create manually, so I just removed the default ground. :slight_smile:

Thanks for the quick answer @Blake .

Problem is, your solution only works if the animation keeps looping forever.

Adjusted the playground: Character performs 3 attacks now, then goes back to idle – at the starting position, which is not what I need :thinking:

Oops sorry, I didn’t think of that, but now it’s time to go and get up for breakfast… Will try to help later if still needed thou. :slight_smile:

PS, here’s the updated PG with the ground flickering fixed for now at least (the earlier version had some extra code that I forgot to delete).

EDIT: actually better to just use createGround option when creating it like above edited PG. LOL I never noticed that option before so have just been disposing it. :blush:

Would be very thankful if you’d find the time later. I already spent good amounts of my weekend on this, without really getting anywhere. I am quite honestly a bit frustrated at this point :see_no_evil:

Since it’s already past dinner time for me, not sure I’ll be able to answer right away.

Thanks again for helping out :relieved:

1 Like

@panepeter

Something like this? https://playground.babylonjs.com/#YIU90M#703

The walking forward is part of the sword attack animation. During the sword attack animation, the position of the model shouldn’t be changed. Otherwise you are increasing the moving distance of the original animation. I.e you don’t need rootMesh.position.z += 0.015.

Only at the moment you switch from sword attack anim to idle, you “teleport” the mesh position to the ending position of sword attack.

Cool, that looks pretty neat already. Thanks!

Hope I can take a look in depth later today, now my day-job is calling :laughing:

One quick question already though: how did you come up with the 3.35 value? Just trial and error? Or is there a way to calculate that? (sort of what I described with getting the bone position)

You need to be able to eye measure the distance to qualify as a babylon.js developer. :smile:

It was trial and error. I guess there is smarter way like calculate the world position of a particular bone at first frame and last frame, but I need to get back to do my boring day job and didn’t try it.

I think you can also do something like this.

Subdivide your ground:

    const ground = BABYLON.MeshBuilder.CreateGround("ground", {
        width: 3,
        height: 20,
        subdivisionsY: 200
    })

Then use babylon debug tool to turn on the wireframe mode on the ground material. Since ground height is 20 and subdivided to 200 segments. Each segment is 0.1.

You can then count the segments.

Being encouraged by your comment, I tried again using the bone position. Odd that it works now, since that was one of the first things I tried :roll_eyes: But, good news nonetheless :tada:

There’s just one little thing that’s left to solve: the position looks accurate now, but there is a little “glitch” when applying .addInPlace and .stop inside the onAnimationLoopObservable. I think the character is out of place for a single frame?! Anybody got an idea why that’s happening (that is, how I can prevent it)?

The problem didn’t occur in your playground, where you changed the position and called stop() inside the setTimeout. So I guess I could get rid of it doing some rearranging, but the current structure feels cleaner to me. And I’d like to understand why the glitch happens, instead of just circumventing it.

Thanks again for taking the time to answer :pray: Hope your day job isn’t too boring after all :wink:

1 Like

Hi @panepeter

I don’t know exactly what was wrong. I tried to clean up the state transition in your PG. I also changed onBeforeRenderObservable to onAfterRenderObservable. Then it worked:

I guess onBeforeRenderObservable is the beginning of the a sword attack frame. If you stop sword attack animation, this frame is still played. Thus causing the flicking. I guess onAnimationLoopObservable also has similar effect since I wasn’t able to fix the flicking issue in your PG by using onAfterRenderObservable without other clean ups.

1 Like

Hello @panepeter just checking in, was your question answered?