Issue with Character Controller Deceleration

Hi guys!
Sorry if this has been answered elsewhere but I couldn’t find anything. Basically my issue is that the Character Controller seems to stop working after the joystick is released. Not instantly, but rather a quarter second after the fact.
This doesn’t appear to happen if I don’t apply the speed variable to the movement direction variable. Acceleration works fine, but deceleration just seems to get cut off before being finished, and instead of smoothly slowing down to a speed of 0, the character starts slowing down for a quarter second before coming to a total stop.

Movement Code

void ApplyMovement(){
        Vector3 MovementDir = new Vector3();

        Vector3 camForward = Camera.main.transform.TransformDirection(Vector3.forward);
        camForward.y = 0;
        camForward = camForward.normalized;
        Vector3 camRight  = new Vector3(camForward.z, 0, -camForward.x);
        float moveHorizontal = Input.GetAxis ("Horizontal");
        float moveVertical = Input.GetAxis ("Vertical");

        MovementDir = (moveHorizontal * camRight  + moveVertical * camForward).normalized ;
        SetSpeed ();
        MovementDir *= Speed;
      
        comCharacterController.Move (MovementDir);
        Debug.Log(comCharacterController.velocity);
    }

Speed Code

void SetSpeed(){
        if (Input.GetAxis ("Vertical") != 0f || Input.GetAxis ("Horizontal") != 0f) {
            if(Speed < SpeedMax || Speed > -SpeedMax){
                Speed = Mathf.Lerp(Speed, SpeedMax, Acceleration * Time.deltaTime);
                Mathf.Clamp(Speed, -SpeedMax, SpeedMax);
            }
        } else if (Input.GetAxis ("Vertical") == 0f && Input.GetAxis ("Horizontal") == 0f) {
            Speed = Mathf.Lerp(Speed, 0f, Deceleration* Time.deltaTime);
        }
    }

Look at how you’re computing MovementDir. You’ll have a vector of zero, so it doesn’t matter what your Speed is, it will be zero. Velocity is determined by your last Move() so it will also be zero.

1 Like

Ooooh…that makes sense…
I’m not sure what the best way to fix that would be. Is there anything simple I can do?

Easy? Varying degrees of easy I suppose ;). Keep track of your last velocity. If your input MovementDir is zero, then instead of MovementDir *= Speed, you can do MovementDir = LastVelocity * BrakingDeceleration. This will work when letting go, but you’ll also be able to instantly change directions (you’ll have no ACTUAL deceleration/acceleration).

To do actual accel/decel (like you’d have in a car game, or on skating on ice) you’ll need to feed your MovementDir into an Acceleration vector, and have that drive Velocity (just like real physics). You’d then Move() with that Velocity (so you’re feeding in Velocity, rather than reading it out). Some platformers don’t follow that model.

1 Like