Weird animation when mixing animator controller and playable animation clip

Hello! =)

I want to make an advanced animation system for our game that uses Animator as a base and Playables API for additional needs (for combo attacks, some complex interactions, etc.). Basically, I want to use Animator, and at the same time, I want more low-level control.

When mixing AnimatorControllerPlayable and AnimationClipPlayable with AnimationLayerMixerPlayable, the animation looks crooked:
8146283--1057946--WeirdAnimation.gif

In all three cases, I use the following Avatar Mask:

Code, which is used for the second (middle) character:

using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;

public class SetupPlayables : MonoBehaviour
{
    [SerializeField]
    private Animator _animator;
    [SerializeField]
    private AnimationClip _clip;
    [SerializeField]
    private AvatarMask _mask;
    [SerializeField]
    private bool _applyFootIk = false;
    [SerializeField]
    private bool _applyPlayableIk = false;
    [SerializeField, Range(0, 1)]
    private float weight1 = 1;
    [SerializeField, Range(0, 1)]
    private float weight2 = 1;
 
    private AnimationLayerMixerPlayable _mixerPlayable;

    private void Start()
    {
        PlayableGraph playableGraph = PlayableGraph.Create(name + " (Custom)");
        AnimationPlayableOutput playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", _animator);

        _mixerPlayable = AnimationLayerMixerPlayable.Create(playableGraph, 2);
        _mixerPlayable.SetLayerMaskFromAvatarMask(1, _mask);
        playableOutput.SetSourcePlayable(_mixerPlayable);

        AnimatorControllerPlayable controllerPlayable =
            AnimatorControllerPlayable.Create(playableGraph, _animator.runtimeAnimatorController);
        playableGraph.Connect(controllerPlayable, 0, _mixerPlayable, 0);
        _animator.runtimeAnimatorController = null;
 
        AnimationClipPlayable clipPlayable = AnimationClipPlayable.Create(playableGraph, _clip);
        clipPlayable.SetApplyFootIK(_applyFootIk);
        clipPlayable.SetApplyPlayableIK(_applyPlayableIk);
        playableGraph.Connect(clipPlayable, 0, _mixerPlayable, 1);

        playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime);
        playableGraph.Play();
    }

    private void Update()
    {
        _mixerPlayable.SetInputWeight(0, weight1);
        _mixerPlayable.SetInputWeight(1, weight2);
    }
}

This is what the PlayableGraph looks like for the second (middle) character:

I also prepared a project so that I could get into what was going on and experiment:
https://github.com/Bodix/Animancer-Layers-Bug

Why it contains Animancer It all started when I installed Animancer. The main killer feature of this asset for me is HybridAnimancerComponent: it allows to mix the work of RuntimeAnimatorController and animations from the code. It was when working with Animancer that I noticed this bug. I wrote the issue to the developer of the plugin, he said it was a Playables API bug. I decided to double-check and it really turned out to be true.

If you have any idea why this is happening, I would be VERY grateful.

Is there any chance you could use Generic animations instead of Humanoid? It might be something weird that the Humanoid system is doing which Generic might not do so it’s probably worth trying if you can (i.e. if your animations are actually made for your specific character rig so you don’t need the Humanoid retargeting system).

Unfortunately, Generic is not my case, because I use characters and animations from different packs and the rigs in them are different. Also, animations are already Humanoid.

Bump

just a guess:
try baking the root transform rotation

@Kybernetik, @bobadi Thank you for your responses!

Tried it, doesn’t help.

The problem still exists.

Just curious, have you tried ensuring that your animator.runtimeAnimatorController is set to null?

I do this in my own scripts that use animation playables because the blending with my own AnimatorControllerPlayable can give incorrect results if Unity’s internal animator.playableGraph is doing its own thing, despite me messing around with AnimationPlayableOutput’s sorting orders and such.

So I prevent Unity from using its own playable graph by setting the Animator’s animator controller field to null in the inspector (or also checking through C# code), and then using the animator controller in my own script.
Not sure if this helps your situation, but figured I’d ask!

P.S. - I haven’t tried using AnimationLayerMixerPlayables before.
I wish they documented the difference between those and AnimationMixerPlayables better, since those are what I’m used to.

Layer mixers let you assign an AvatarMask to each layer and set them to additive, so the math is a bit more complex than regular mixers.

Ahh wow, thanks for your insight! This makes sense

In case anyone comes across this in the future as I did, I have just found the solution buried away in a “won’t fix” ticket for unity:

“The AnimatorControllerPlayable is indeed an unexpected behavior, but we cannot change this without breaking many existing projects. The reason the tilting exist is because for humanoids, we apply a Mass center retargeting for single layer animator controller with humanoid.
A simple workaround is to simply add an empty layer to the animator controller”

So the issue is specific to single layer animator controllers when using humanoid. Adding an additional, empty layer to the animator controller fixed it for me. It was so simple I didn’t believe it at first, but it works!