Hello,

Please see the attached gif.

I'm playing a looping idle animation in track 0, and trying to sometimes display alternate idle animation in track 1.

The gif snapping behavior occurs when using the following method:

  • Add/set empty animation in track 1
    -Set alternate idle animation in track 1, mix duration = 2f
    -Add empty animation in track 1, mix duration 2f.

I've tried grabbing the track entry returned from setting the alternate idle animation and manually setting .mixduration = 2f that way, but nothing seems to work.

Any ideas?

EDIT: Reference to snapping behavior refers to the hand that should smoothly move to the hip instead of snapping to it.

Related Discussions
...

While I'm not completely sure how you set the alternate idle animation, I assume that the problem is that you are calling SetAnimation() to set your idle animation immediately after calling AddEmptyAnimation(), and SetAnimation is thus discarding the queued but never-played empty animation as if it was never added (see the documentation here). Instead you might want to call AddAnimation() to not discard the queued empty animation (as described here).

You can find a related code sample in this forum posting which might help:
https://esotericsoftware.com/forum/d/16533-no-mix-at-a-higher-track-sometimes/6

  • Bearbeitet

Hey Harald,

Thanks for posting the related code. Doing a copy/paste of Jamez0r's solution of mixing from empty animation if track is null yield the same result of arm snapping to wrist. In this case I'm testing on a single front view game object, adding idle animation with mix duration = 1f.

Am I missing something in the code here?

`

        if ( skeletonAnimation.state.GetCurrent (trackAlternateIdleStance) == null ) {
            Debug.Log ("null track, using add animation");
            skeletonAnimation.AnimationState.SetEmptyAnimation (trackAlternateIdleStance, .2f);
            entry = skeletonAnimation.AnimationState.AddAnimation (trackAlternateIdleStance, "idle_touch", false, 0);
        } else {
            Debug.Log ("track has animation, using set animation");
            entry = skeletonAnimation.AnimationState.SetAnimation (trackAlternateIdleStance, "idle_touch", false);
        }

        entry.MixDuration = mixDuration;`

You can pass zero, ie SetEmptyAnimation(trackAlternateIdleStance, 0);, rather than mixing to the empty animation over 0.2s. Since you aren't playing an animation currently, so there is no animation to mix from to the empty animation.

Next, you set idle_touch, but what is the mix duration from empty to idle_touch? It is zero. The mix duration between two animations is set on the second animation. Try:

SetEmptyAnimation(trackAlternateIdleStance, 0);
TrackEntry entry = AddAnimation (trackAlternateIdleStance, "idle_touch", false, 0);
entry.MixDuration = 0.2;

Hey Nate,

Thanks for the tip. I've tried using your method with a mix time of 1f on the track entry, still getting the same result of the arm snapping to the wrist.

skeletonAnimation.AnimationState.SetEmptyAnimation (trackAlternateIdleStance, 0);
TrackEntry entry = skeletonAnimation.AnimationState.AddAnimation (trackAlternateIdleStance, "idle_touch", false, 0);
entry.MixDuration = 1f;

What works however is using your method on the same track index 0 that is playing an idle animation, then the hand smoothly interpolate to the wrist:

skeletonAnimation.AnimationState.SetEmptyAnimation (trackIdle, 0);
TrackEntry entry = skeletonAnimation.AnimationState.AddAnimation (trackIdle, "idle_touch", false, 0);
entry.MixDuration = 1f;

Not sure why interpolating from empty animation to idle_touch doesn't work on track 1.

While I'm running out of ideas, are you perhaps exporting the skeleton with Animation cleanup enabled (which removes keys identical to the setup pose, as also explained in this posting)? If so, please have a try whether disabling Animation cleanup fixes your issue.

If it does not fix your problem, could you please send us a minimal Unity project which still shows this isue? You can send it as a zip package to contact@esotericsoftware.com, briefly mentioning this forum thread URL so that we know the context. Then we can have a look.

Hey Harald,

Indeed animation cleanup is not enabled since that always seems to throw a wrench in the machinery when using multiple tracks.

Project has been sent your way.

  • Bearbeitet

@raeiraei Thanks for sending the reproduction project, we received everything.

The cause of your issue it your basic skeleton setup (how you are switching IK / FK control). You are using a duplicate arm IK / FK setup with separate bones for IK and FK controlled bones (nothing wrong with that yet).

One common way to switch between an IK and FK rig in animation is to use constraints to constrain the FK bones to the respective IK bone location when you want to have IK to take control. Your constraint mix value is then set to either 0.0 to be freely positioned as FK, or 1.0 to let the bone follow the IK bone 100%. A similar approach could be to have IK bones, FK bones and a third set of attachment bones, with attachment bones location being constrained to IK bones or FK bones by inverse weights respectively. You would then have the attachments only attached at a single set of bones.

In your setup however, you have two identical sets of attachments used for the IK bones and FK bones, with the inactive rig disabling the attachment visibility (so IK attachments visible on IK bones, or FK attachments visible on FK bones). This is the cause of your problem, since at the start of your idle_touch animation, your attachment at one bone is disabled and another (similar looking) attachment at another bone is enabled. Now these obviously won't magically blend their position, since the bones themselves don't move at all, it's just attachments that are disabled at location A and enabled at location B.