Root motion with multiple layers work around

I encountered a problem in Animator when using multiple layers with root motion. These multiple layers have some animations that have root motion curves in them, which are supposed to override the root motion on layers below them. I encountered a problem where after going into an Animator state with root motion on layer 1, all of the Animator states on that layer would override the root motion on layer 0 even when the state on layer 1 had no root motion, resulting in the player staying in place. I figured out that by rebinding the Animator after leaving the state on layer 1 with root motion, I could fix this behaviour. I then made a method which saves the state information and parameters, rebinds the Animator, and then sets the correct animation, time, and parameters. I then call this from a StateMachineBehaviour, OnStateExit.

/// <summary>
/// Reseting the animator while retaining the state of the animator. 
/// Created because of a bug in the animator with root motion in multiple layers. 
/// NOTE: triggers don't retain their state.
/// </summary>
public void ResetAnimator()
{
    Debug.Log("Reset Animator");

    // Get the layers
    int layerCount = _animator.layerCount;
    
    List<AnimatorStateInfo> stateInfos = new List<AnimatorStateInfo>();

    for (int i = 0; i < layerCount; i++)
    {
        stateInfos.Add(_animator.GetCurrentAnimatorStateInfo(i));
    }

    // Get the parameters
    int parameterCount = _animator.parameterCount;

    List<AnimatorControllerParameter> parameters = new();
    Dictionary<int, bool> bools = new();
    Dictionary<int, float> floats = new();
    Dictionary<int, int> ints = new();

    for (int i = 0; i < parameterCount; i++)
    {
        AnimatorControllerParameter parameter = _animator.parameters[i];

        parameters.Add(parameter);
        
        switch (parameter.type)
        {
            case AnimatorControllerParameterType.Bool:
                bools.Add(i, _animator.GetBool(parameters[i].name));
                break;
            case AnimatorControllerParameterType.Float:
                floats.Add(i, _animator.GetFloat(parameters[i].name));
                break;
            case AnimatorControllerParameterType.Int:
                ints.Add(i, _animator.GetInteger(parameters[i].name));
                break;
        }
    }

    // Rebind the animator
    _animator.Rebind();

    // Set the layers
    for (int i = 0; i < layerCount; i++)
    {
        _animator.Play(stateInfos[i].fullPathHash, i, stateInfos[i].normalizedTime);
    }

    // Set the parameters
    for (int i = 0; i < parameterCount; i++)
    {
        switch (parameters[i].type)
        {
            case AnimatorControllerParameterType.Bool:
                _animator.SetBool(parameters[i].name, bools[i]);
                break;
            case AnimatorControllerParameterType.Float:
                _animator.SetFloat(parameters[i].name, floats[i]);
                break;
            case AnimatorControllerParameterType.Int:
                _animator.SetInteger(parameters[i].name, ints[i]);
                break;
        }
    }
}

This is possibly a bug. Quite annoying but hope this helps somebody.

Edit. There was a logical issue in the initial implementation of saving parameters and setting them.