Blend Tree stuttering strafe/transsitions

Hello there, we are experiencing some problems with our blend tree setup inside our Rootmotion Playercontroller. Our idle is outside of the walk/run blendtree and we are using start and stop motions. Everything is fine really, except for if you want to strafe from left to right too quick and especially when trying to transition from walking forward to backward and trice versa. It looks really stuttery and feels uncomfortable in those cases. We looked into the kubold playmaker controller and we are trying to copy it one by one just with C# code. Animator and transitions are all the same between us and theirs. It’s a problem that has been bugging us for a while now with multiple playercontrollers, with the only way to fix this beeing to include the idle animation inside the walk blendtree, but for this project we want to know how it’s really done. Any ideas?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasicPlayerController : MonoBehaviour
{
    #region Vabrialen

    // Grounded
    public Collider mCharacterCollider;
    public float mGroundedOffset = 0.1f;
    float mDisstanceToTheGround;

    Animator mAnimator;
    Transform mCamera;
    Rigidbody mRigidbody;

    // Input Settings
    float mHorizontal;
    float mVertical;
    float mRunFactor = 0.5f;

    float InputMagnitude;
    float InputAngle;
    Vector3 rDirection;

    bool IsFalling = false;

    #endregion

    #region Start

    private void Start()
    {
        mAnimator = this.GetComponent<Animator>();
        mCamera = Camera.main.transform;
        mRigidbody = this.GetComponent<Rigidbody>();

        if (mAnimator == null || mRigidbody == null ||
            mCharacterCollider == null)
            return;

        mAnimator.speed = 1.05f;
        mAnimator.applyRootMotion = true;
        mDisstanceToTheGround = mCharacterCollider.bounds.extents.y;
    }

    #endregion

    #region Update

    private void Update()
    {
        CheckGrounded();
        ControllerInput();
    }
    #endregion

    #region LateUpdate

    // Maybe FixedUpdate ???
    void LateUpdate()
    {
        if (mAnimator == null || mCamera == null)
            return;

        rDirection = new Vector3(mHorizontal, 0, mVertical);

        InputMagnitude = rDirection.magnitude;

        InputAngle = Vector2.SignedAngle(new Vector2(transform.forward.x, transform.forward.z), new Vector2(Camera.main.transform.forward.x, Camera.main.transform.forward.z));
        InputAngle += Vector3.SignedAngle(transform.TransformVector(rDirection), transform.forward, Vector3.up);
        InputAngle = InputAngle * -1;

        mAnimator.SetFloat("InputMagnitude", InputMagnitude *= mRunFactor);

        if (InputMagnitude > 0.2f)
        {
            RotateToCameraDirection(mCamera);

            mAnimator.SetFloat("WalkStartAngle", InputAngle);
            mAnimator.SetFloat("WalkStopAngle", InputAngle);

            mAnimator.SetFloat("Horizontal", rDirection.x *= mRunFactor, 0.25f, Time.deltaTime);
            mAnimator.SetFloat("Vertical", rDirection.z *= mRunFactor, 0.25f, Time.deltaTime);
            mAnimator.SetFloat("InputAngle", InputAngle, 0.15f, Time.deltaTime);
        }

        mAnimator.SetBool("IsFalling", !IsFalling);
    }

    #endregion

    #region Functions

    private void RotateToCameraDirection(Transform mLookTransform)
    {
        Quaternion rotation = Quaternion.LookRotation(mLookTransform.forward);
        rotation = new Quaternion(0.0f, rotation.y, 0.0f, rotation.w);

        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 5f);
    }

    public bool CheckGrounded()
    {
        bool IsGrounded = Physics.Raycast(mCharacterCollider.bounds.center, Vector3.down, mDisstanceToTheGround + mGroundedOffset);
        return IsFalling = IsGrounded;
    }

    public void OnAnimatorMove()
    {
        Vector3 rootMotion = mAnimator.deltaPosition;
        Vector3 currentVelocity = mRigidbody.velocity;
        Vector3 animatorVelocity = rootMotion / Time.deltaTime;

        animatorVelocity.y = currentVelocity.y;
        mRigidbody.velocity = animatorVelocity;

        Vector3 animatorAngularVelocity = mAnimator.angularVelocity;
        mRigidbody.angularVelocity = animatorAngularVelocity;
    }

    #endregion

    #region Input

    public void ControllerInput()
    {
        mHorizontal = Input.GetAxisRaw("Horizontal");
        mVertical = Input.GetAxisRaw("Vertical");

        // Test Running
        mRunFactor = Input.GetKey(KeyCode.LeftShift) ? mRunFactor = 2.0f : mRunFactor = 0.5f;
    }

    #endregion
}

hi, have you found the cause of this?

No Not really i have try to start again with a Controller but i run all time in the same issue

I noticed this can be betterd with input/blendtree parameter lerpin.

seem to happen if the blendtree values change quickly, the com gets offset
but still no answer what causes it. might be a bug in unity’s com calculating

okay, this is blending issue
have you debug.log the blendtree input? this ? mRunFactor = 2.0f : mRunFactor = 0.5f; is it a value switch?
but to me this anim looks like it always (or is it just while movin slow) goes back to idle