Hi,

First I want to disclose that I'm completely new to Spine and I've yet to fully learn the basics.

I've recently worked with an Artist on Fiverr for animating a character in Unity. They were using Run-time 3.8.

I've purchased Spine Pro and exported the files in 4.2 and installed the 4.2 packages in Unity and re-created my sprites with SkeletonAnimation.

Now when the character is landing after the Jump animation is completed and transitioning to Idle animations, you can see one leg stretching to the ground.

I've just read that 4.2 has new physics integrated with Unity. Could this behavior tied to the new physics?

What parameters do I need to set to cancel that behavior? Or even better, how can I fix this behavior and keeping the new physics?

Thank you.

    Related Discussions
    ...

    unabashedly_reggie Welcome to the Spine forum! 🙂

    I guess this is because the IK constraint settings for the next animation (Idle) are applied too early in the mix. I think that you probably have the IK constraint mix set to zero and switched to FK for the Jump animation, and the IK mix set to 100 for the Idle animation. I think the leg is stretched because this switch is made before the jump animation finishes playing.
    How are you setting the idle animation after the jump animation? Please show us the script that sets the animations.

    I've been lurking this forum for a little while and I love it. I just love how quickly the staff answers questions. I'm using State Machine logic, so I'll include the parts that change to Jumping and part that changes to Idle.

      public void SetAnimation(string animationName, bool loop)
        {
            skeletonAnimation.AnimationState.SetAnimation(0, animationName, loop);
        }

    When the jump button is pressed it calles the above:

    player.SetAnimation("Jump", false);

    Then there's a check to see if the player is grounded before switching to Idle:

    if (player.IsNearWall() && player.JumpBuffered)
            {
                ChangeState(new WallJumpState(player, stateMachine));
            }
            else if (player.IsGrounded() && Time.time - jumpStartTime > player.MinJumpDuration)
            {
                if (player.MoveInput != 0)
                {
                    ChangeState(new WalkState(player, stateMachine));
                }
                else
                {
                    Debug.Log("Player is Grounded - Switching to Idle");
                    ChangeState(new IdleState(player, stateMachine));
                }
            }

    The ChangeState will then call:

    player.SetAnimation("Idle", true);

    I do have questions regarding your explanation, is the mix something that can be set with the SkeletonAnimation or that's more when using the Animator in Unity?

      unabashedly_reggie Thanks for showing me the script! I think it would be better to add an event key to the frame where the character's foot touches the ground in the Jump animation, and then set the Idle animation. To make the system respond to events in a specific animation, you can add a delegate like this:

      TrackEntry trackEntry = player.SetAnimation(0, "Jump", false);
      trackEntry.Event += OnLand;

      After that, you can set the Idle animation by checking if the event that was fired matches the event name you want to respond to. In the example below, the event key "land" is set to the frame where the character's foot touches the ground in the Jump animation, and the Idle animation will be triggered when that event is fired:

      public void OnLand(Spine.TrackEntry trackEntry, Spine.Event e) {
           if (e.Data.Name == "land") {
                  player.SetAnimation(0, "Idle", true);
           }
      }

      I do have questions regarding your explanation, is the mix something that can be set with the SkeletonAnimation or that's more when using the Animator in Unity?

      Mixing is available when using SkeletonAnimation. Specifically, the AnimationState in the SkeletonAnimation component manages the state of all currently playing and queued animations and performs mixing between animations. For more details about Mix, please refer to the general runtime guide: https://esotericsoftware.com/spine-applying-animations#Mix-times

      Thanks for telling me about events! I'm looking forward to investing time in guides and learning the tool!

      Based on your event solution, wouldn't that mean that all my jumps would have to be the same height in order for the animation to complete before reaching ground? In my video the issue happens for shorter jump.

      One solution I've seen with Animation within Unity would be to speed up the animation based on the velocity of the jump. This seems to be something I could do based methods I saw (AnimationState.TimeScale).

      What do you think of that approach?

        unabashedly_reggie

        In my video the issue happens for shorter jump.

        Hmm, it's true that the stretching only occurs on shorter jumps, but I think the issue of the foot IK switching earlier than it touches the ground occurs just before landing on all jumps. Even on high jumps, the pose of the leg just before landing is not very clean (around 0:11 in the video):

        One solution I've seen with Animation within Unity would be to speed up the animation based on the velocity of the jump. This seems to be something I could do based methods I saw (AnimationState.TimeScale).

        What do you think of that approach?

        I think that is actually a common approach. Another way to create variations in jump height in the same jump animation is to split the jump animation into separate parts for the jumping up, ascending, descending and landing phases, then make the length of time that ascending and descending are played change according to the height of the jump. (You could use the same animation for both ascending and descending.)

          Misaki

          Interesting!

          Would you separate the jump animation using tags or actually 3 different animations?

            unabashedly_reggie Unfortunately, Spine does not have a tag function. The only thing that can be used to indicate some kind of timing at runtime is the event key.
            I think splitting the animation into 3 different animations is the most common way. If you queue animations on a specific track with AddAnimation() with a mix duration of 0, you can play multiple animations sequentially without mixing them.