Strange lerping behaviour

Hello,

i have been playing around with a first person controller and i’ve encoutered problem that i can’t comprehend. I have to functions to smooth the crouching as well as the uncrouching. When i trigger the crouching i have a smooth transition from the standheight to the crouchheight. However when i release the key the transition from the crouchheight to standheight with the stand() function stutters extremely. I’ve played around with the parameters and i’ve tried smoothdamp. I couldn’t find anything on youtube or the docs that helped me resolving this issue.

public float standheight = 2f;
public float crouchheight = 1.2f;
private float standdelay = 8f;
private float crouchdelay = 8f;

public void Crouch()
{
if (charactercontroller.height > crouchheight)
{
charactercontroller.height = Mathf.Lerp(charactercontroller.height, crouchheight, crouchdelay * Time.deltaTime);
}
else
{
charactercontroller.height = crouchheight;
}
}

public void Stand()
{
if (charactercontroller.height < standheight)
{
//float x = 0.0f;
charactercontroller.height = Mathf.Lerp(charactercontroller.height, standheight, standdelay * Time.deltaTime);
//charactercontroller.height = Mathf.SmoothDamp(charactercontroller.height, standheight, ref x, 0.3f);
}
else
{
charactercontroller.height = standheight;
}
}

Don’t think you’ve posted quite enough code to properly determine it, but my guess is that the crouch function is still running, and the stutter is because its trying to run both at the same time

use code tags

Doesn’t stutter for me
What does the code in update that calls this code look like?

hpjohn i thought that too, however its not the case.
this is what the full script looks like

public enum CharacterHeight
{
    Walk,
    Chrouch,
    Prone
}

public enum CharacterSpeed
{
    Sprint,
    Normal,
    Aim
}

public enum CharacterState
{
    Jumping,
    Walking,
    WalkAiming,
    WalkSprinting,
    Crouching,
    CrouchAiming,
    CrouchSprinting,
    Proning,
    ProneAiming,
    ProneSprinting
}

public class Playermovement : MonoBehaviour
{
    private bool isWalking;
    private bool isCrouching;
    private bool isProneing;
    private bool isJumping;


    //InputVariables
    public float inputX;
    public float inputY;
    private float gravity = 20;
    private float inputModifyFactor;
    private int antibunnyhopfactor = 1;
    private int jumptimer;
    public bool isGrounded = true;
    private Vector3 moveDirection;



    private float yJumpForce = 8.0f;

    //ControllerHeight
    public float standheight = 2.0f;
    public float crouchheight = 1.2f;
    public float proneHeight = 0.3f;
    private float standdelay = 10f;
    private float crouchdelay = 8f;
    private float proneDelay = 8f;


    //neccessary Components
    public CharacterController charactercontroller;
    public Transform characterTransform;

    [Header("MovementSpeedVAriables")]
    //MovementSpeedVAriables
    public float currentSpeed = 0f;
    public float walkSpeed = 4f;
    public float waklkAimSpeed = 3.5f;
    public float waklkSprintSpeed = 6f;
    public float crouchSpeed = 2f;
    public float crouchAimSpeed = 1.5f;
    public float crouchSprintSpeed = 3f;
    public float proneSpeed = 1f;
    public float proneAimSpeed = 0.5f;
    public float proneSprintSpeed = 1.5f;
    public float jumpspeed = 4f;



    public CharacterHeight characterHeight;
    public CharacterState characterState;
    public CharacterSpeed characterSpeed;



    // Start is called before the first frame update
    void Start()
    {
        characterHeight = CharacterHeight.Walk;
        characterState = CharacterState.Walking;
        characterSpeed = CharacterSpeed.Normal;
    }

    // Update is called once per frame
    void Update()
    {
        DetermineMovementDirectionByInput();
    }


    private void DetermineMovementDirectionByInput()
    {

        inputX = InputManager.GetHorizontalMovementInput();
        inputY = InputManager.GetVerticallMovementInput();
        inputModifyFactor = (inputX != 0.0f && inputY != 0.0f) ? .7071f : 1.0f;



        if (isGrounded)
        {

            if (InputManager.GetKeyDown(ActionCode.Jump) && characterHeight != CharacterHeight.Prone)
            {
                if (jumptimer >= antibunnyhopfactor)
                {
                    characterHeight = CharacterHeight.Walk;
                    characterState = CharacterState.Walking;
                    moveDirection.y = yJumpForce;
                    jumptimer = 0;
                    return;
                }
            }


            if (InputManager.GetKeyDown(ActionCode.Jump) && characterHeight == CharacterHeight.Prone)
            {
                characterHeight = CharacterHeight.Walk;
                return;
            }

            if ((InputManager.GetKeyDown(ActionCode.Prone)))
            {
                if (characterHeight == CharacterHeight.Prone)
                {
                    characterHeight = CharacterHeight.Chrouch;
                }
                else
                {
                    characterHeight = CharacterHeight.Prone;
                }
            }

            //Determine Chrouch depending on Chrouch Options
            if ((InputManager.GetKeyDown(ActionCode.Crouch)))
            {
                if (characterHeight == CharacterHeight.Chrouch)
                {
                    characterHeight = CharacterHeight.Walk;
                }
                else
                {
                    characterHeight = CharacterHeight.Chrouch;
                }

            }



            //Determine ADS depending on ADS Options
            if (GameOptions.holdAimDownSight)
            {
                if (GameOptions.holdSprint) {

                    characterSpeed = CharacterSpeed.Normal;
                    SetNormalStateByCharacterSpeed();

                    if ((InputManager.GetKey(ActionCode.AimDownSight)))
                    //Determine wether we are sprinting right now
                    {
                        characterSpeed = CharacterSpeed.Aim;
                        SetAimStateByCharacterSpeed();
                    }
                }
                else
                {
                    if (InputManager.GetKey(ActionCode.AimDownSight))
                    //Determine wether we are sprinting right now
                    {
                        characterSpeed = CharacterSpeed.Aim;
                        SetAimStateByCharacterSpeed();
                    }
                    else if (characterSpeed == CharacterSpeed.Aim && !InputManager.GetKey(ActionCode.AimDownSight))
                    //Determine wether we are sprinting right now
                    {
                        characterSpeed = CharacterSpeed.Normal;
                        SetNormalStateByCharacterSpeed();
                    }
                }
            }
            else
            {
                //Determine wether we are aiming right now
                if ((InputManager.GetKeyDown(ActionCode.AimDownSight)))
                {
                    if (characterSpeed == CharacterSpeed.Aim)
                        characterSpeed = CharacterSpeed.Normal;
                    else
                        characterSpeed = CharacterSpeed.Aim;
                }
                //Set Sprintspeed according to our characterheight-state
                if (characterSpeed == CharacterSpeed.Aim)
                    SetAimStateByCharacterSpeed();
                else if (characterSpeed == CharacterSpeed.Normal)
                    SetNormalStateByCharacterSpeed();

            }


            //Determine Chrouch depending on Chrouch Options
            if (GameOptions.holdSprint)
            {
                if (InputManager.GetKey(ActionCode.Sprint) && InputManager.GetKey(ActionCode.MoveForward))
                //Determine wether we are sprinting right now
                {
                    characterSpeed = CharacterSpeed.Sprint;
                    SetSprintStateByCharacterSpeed();
                }
                else if (characterSpeed == CharacterSpeed.Sprint && !InputManager.GetKey(ActionCode.AimDownSight))
                //Determine wether we are sprinting right now
                {
                    characterSpeed = CharacterSpeed.Normal;
                    SetNormalStateByCharacterSpeed();
                }
            }
            else
            {
                //Determine wether we are sprinting right now
                if (InputManager.GetKeyDown(ActionCode.Sprint))
                {
                    if (characterSpeed == CharacterSpeed.Sprint)
                        characterSpeed = CharacterSpeed.Normal;
                    else if(InputManager.GetKey(ActionCode.MoveForward))
                        characterSpeed = CharacterSpeed.Sprint;
                }

                if (characterSpeed == CharacterSpeed.Sprint && !InputManager.GetKey(ActionCode.MoveForward))
                {
                        characterSpeed = CharacterSpeed.Normal;
                }


                //Set Sprintspeed according to our characterheight-state
                if (characterSpeed == CharacterSpeed.Sprint)
                    SetSprintStateByCharacterSpeed();
                else if (characterSpeed == CharacterSpeed.Normal)
                    SetNormalStateByCharacterSpeed();
            }


            SetCurrentSpeedByCharacterSpeedState();
            SetCurrentHeightByCharacterHeightState();

            moveDirection.x = inputX * currentSpeed * inputModifyFactor;
            moveDirection.z = inputY * currentSpeed * inputModifyFactor;
            moveDirection = transform.rotation * moveDirection;

        }
        else
        {
            jumptimer++;

        }


        moveDirection.y -= gravity * Time.deltaTime;
        isGrounded = (charactercontroller.Move(moveDirection * Time.deltaTime) & CollisionFlags.Below) != 0;
    }

    public void Crouch()
    {

        if (charactercontroller.height > crouchheight)
        {
            charactercontroller.height = Mathf.Lerp(charactercontroller.height, crouchheight, crouchdelay * Time.deltaTime);
        }
        else
        {
            charactercontroller.height = crouchheight;
        }
    }

    public void Prone()
    {

        if (charactercontroller.height > proneHeight)
        {
            charactercontroller.height = Mathf.Lerp(charactercontroller.height, proneHeight, proneDelay * Time.deltaTime);
        }
        else
        {
            charactercontroller.height = proneHeight;
        }
    }

    public void Stand()
    {

        if (charactercontroller.height < standheight)
        {
            charactercontroller.height = Mathf.Lerp(charactercontroller.height, standheight, standdelay * Time.deltaTime);
        }
        else
        {
            charactercontroller.height = standheight;
        }
    }

    public void SetAimStateByCharacterSpeed()
    {
        if (characterHeight == CharacterHeight.Walk)
            characterState = CharacterState.WalkAiming;
        else if (characterHeight == CharacterHeight.Chrouch)
            characterState = CharacterState.CrouchAiming;
        else if (characterHeight == CharacterHeight.Prone)
            characterState = CharacterState.ProneAiming;
    }

    public void SetNormalStateByCharacterSpeed()
    {
        if (characterHeight == CharacterHeight.Walk)
            characterState = CharacterState.Walking;
        else if (characterHeight == CharacterHeight.Chrouch)
            characterState = CharacterState.Crouching;
        else if (characterHeight == CharacterHeight.Prone)
            characterState = CharacterState.Proning;
    }

    public void SetSprintStateByCharacterSpeed()
    {
        if (characterHeight == CharacterHeight.Walk)
            characterState = CharacterState.WalkSprinting;
        else if (characterHeight == CharacterHeight.Chrouch)
            characterState = CharacterState.CrouchSprinting;
        else if (characterHeight == CharacterHeight.Prone)
            characterState = CharacterState.ProneSprinting;
    }

    public void SetCurrentSpeedByCharacterSpeedState()
    {
        switch (characterState)
        {
            case CharacterState.Walking:
                currentSpeed = walkSpeed;
                break;
            case CharacterState.WalkAiming:
                currentSpeed = waklkAimSpeed;
                break;
            case CharacterState.WalkSprinting:
                currentSpeed = waklkSprintSpeed;
                break;
            case CharacterState.Crouching:
                currentSpeed = crouchSpeed;
                break;
            case CharacterState.CrouchAiming:
                currentSpeed = crouchAimSpeed;
                break;
            case CharacterState.CrouchSprinting:
                currentSpeed = crouchSprintSpeed;
                break;
            case CharacterState.Proning:
                currentSpeed = proneSpeed;
                break;
            case CharacterState.ProneAiming:
                currentSpeed = proneAimSpeed;
                break;
            case CharacterState.ProneSprinting:
                currentSpeed = proneSprintSpeed;
                break;
            case CharacterState.Jumping:
                currentSpeed = jumpspeed;
                break;
            default:
                Debug.Log("CharacterState Not Found");
                break;
        }
    }

    public void SetCurrentHeightByCharacterHeightState()
    {
        switch (characterHeight)
        {
            case CharacterHeight.Walk:
                Stand();
                break;
            case CharacterHeight.Chrouch:
                Crouch();
                break;
            case CharacterHeight.Prone:
                Prone();
                break;
            default:
                Debug.Log("CharacterHeight Not Found");
                break;
        }
    }
}

Woah dude… check out @Hikiko66 's post about code tags.

1 Like