Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Issue with Character Controller Deceleration

Discussion in 'Scripting' started by Sushin, Jun 18, 2015.

  1. Sushin

    Sushin

    Joined:
    May 2, 2015
    Posts:
    25
    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
    Code (csharp):
    1. void ApplyMovement(){
    2.         Vector3 MovementDir = new Vector3();
    3.  
    4.         Vector3 camForward = Camera.main.transform.TransformDirection(Vector3.forward);
    5.         camForward.y = 0;
    6.         camForward = camForward.normalized;
    7.         Vector3 camRight  = new Vector3(camForward.z, 0, -camForward.x);
    8.         float moveHorizontal = Input.GetAxis ("Horizontal");
    9.         float moveVertical = Input.GetAxis ("Vertical");
    10.  
    11.         MovementDir = (moveHorizontal * camRight  + moveVertical * camForward).normalized ;
    12.         SetSpeed ();
    13.         MovementDir *= Speed;
    14.      
    15.         comCharacterController.Move (MovementDir);
    16.         Debug.Log(comCharacterController.velocity);
    17.     }
    Speed Code
    Code (csharp):
    1. void SetSpeed(){
    2.         if (Input.GetAxis ("Vertical") != 0f || Input.GetAxis ("Horizontal") != 0f) {
    3.             if(Speed < SpeedMax || Speed > -SpeedMax){
    4.                 Speed = Mathf.Lerp(Speed, SpeedMax, Acceleration * Time.deltaTime);
    5.                 Mathf.Clamp(Speed, -SpeedMax, SpeedMax);
    6.             }
    7.         } else if (Input.GetAxis ("Vertical") == 0f && Input.GetAxis ("Horizontal") == 0f) {
    8.             Speed = Mathf.Lerp(Speed, 0f, Deceleration* Time.deltaTime);
    9.         }
    10.     }
     
    Last edited: Jun 18, 2015
  2. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    434
    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.
     
    Sushin likes this.
  3. Sushin

    Sushin

    Joined:
    May 2, 2015
    Posts:
    25
    Ooooh....that makes sense...
    I'm not sure what the best way to fix that would be. Is there anything simple I can do?
     
  4. Jodon

    Jodon

    Joined:
    Sep 12, 2010
    Posts:
    434
    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.
     
    Sushin likes this.