How to stop accelerating in my car game after releasing the button

Hi!
I’m currently programming a little car game in Unity and I have followed various tutorials already. I have a problem that I can’t figure out how to resolve. When I accelerate the car, it doesn’t stop accelerating when I release “W” or “S”, but it stays at the same value. I’m pretty sure the fix isn’t that hard but I still can’t figure out how to change that.

Underneath you can find my code, I hope someone can help. Thanks!

public class WheelController : MonoBehaviour
{
    public Vector3 originalPos;

    [SerializeField] WheelCollider frontRight;
    [SerializeField] WheelCollider frontLeft;
    [SerializeField] WheelCollider backRight;
    [SerializeField] WheelCollider backLeft;

    [SerializeField] Transform frontRightTransform;
    [SerializeField] Transform frontLeftTransform;
    [SerializeField] Transform backRightTransform;
    [SerializeField] Transform backLeftTransform;

    public float acceleration = 700f;
    public float breakingForce = 300f;
    public float maxTurnAngle = 15f;

    private float currentAcceleration = 0f;
    private float currentBreakForce = 0f;
    private float currentTurnAngle = 0f;

    void Awake()
    {

        //Looking for original Position
        originalPos = transform.position;

    }

    private void FixedUpdate() {

        //Forward & reverse acceleration from w and s keys (vertical axis) & Stopping after some time
        currentAcceleration = acceleration * Input.GetAxis("Vertical");


        //Pressing space --> giving currentBreakForce a value 
        if (Input.GetKey(KeyCode.Space))
            currentBreakForce = breakingForce;
        else
            currentBreakForce = 0f;

        //Acceleration on front wheels
        frontRight.motorTorque = currentAcceleration;
        frontLeft.motorTorque = currentAcceleration;

        frontRight.brakeTorque = currentBreakForce;
        frontLeft.brakeTorque = currentBreakForce;
        backRight.brakeTorque = currentBreakForce;
        backLeft.brakeTorque = currentBreakForce;

        //steering
        currentTurnAngle = maxTurnAngle * Input.GetAxis("Horizontal");
        frontLeft.steerAngle = currentTurnAngle;
        frontRight.steerAngle = currentTurnAngle;

        //Updating the meshes of the wheels
        UpdateWheel(frontLeft, frontLeftTransform);
        UpdateWheel(frontRight, frontRightTransform);
        UpdateWheel(backLeft, backLeftTransform);
        UpdateWheel(backRight, backRightTransform);

    }
    void UpdateWheel(WheelCollider col, Transform trans) {

        //Get state of wheel collider
        Vector3 position;
        Quaternion rotation;
        col.GetWorldPose(out position, out rotation);

        // Set wheel mesh state
        trans.position = position;
        trans.rotation = rotation;

    }
    void Update()
    {
        //Reset Position and Rotation
        if (Input.GetKey("b"))
        {

            transform.position = originalPos;
            transform.localEulerAngles = new Vector3 (0, 90, 0);
        }

    }
}

Its because motorTorque sets acceleration, if it is set to 0 the car doesn’t slow down and has constant velocity. You have to set idle breaking force when you are not accelerating. And also to prevent infinite acceleration you should limit torque based on current RPM.
For example:

    public float idleBreakingForce = 100f;
    public float maxRPM = 100f;
    public AnimationCurve torqueCurve;
...
        //Pressing space --> giving currentBreakForce a value 
        if (Input.GetKey(KeyCode.Space)) {
            currentBreakForce = breakingForce;
        } else {
            currentBreakForce = (Mathf.Abs(currentAcceleration) < 0.1f) ? idleBreakingForce : 0f;
        }

        //Acceleration on front wheels
        frontRight.motorTorque = currentAcceleration * torqueCurve.Evaluate(Mathf.Clamp01(Mathf.Abs(frontRight.rpm) / maxRPM));
        frontLeft.motorTorque = currentAcceleration * torqueCurve.Evaluate(Mathf.Clamp01(Mathf.Abs(frontLeft.rpm) / maxRPM));

The torqueCurve should look like this:
image

Just to be clear, does the car continue to accelerate (velocity keeps increasing), or does it just continue at the current velocity without slowing down?

I think the solution will depend on what the GetWorldPose function is doing. You may also want to add some Debug.Log statements to make sure that the currentAcceleration and currentBreakForce values match your expectations.

Do you have a reason for Updating tire meshes in FixedUpdate?

That’s because applying motorTorque continuously makes the wheel reach high rpm sliding on the surface. When you set the torque back to zero, the wheel keeps spinning and applying force while it reduces its rpm. Read the value WheelCollider.rpm to check out the rpm the wheel is spinning at.

WheelCollider.motorTorque doesn’t apply an acceleration to the vehicle, but to the wheel’s angular velocity (rpm). Applying to much torque too much time just increases the wheel’s rpm.

@MichaI1
So I’ve tried implementing your solution into the code and technically it works, meaning there are no errors shown, but the car is now not moving at all, I’m still kind of new to coding so I’m pretty sure I’ve missed something, could you take a look?

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

public class WheelController : MonoBehaviour
{
    public Vector3 originalPos;

    [SerializeField] WheelCollider frontRight;
    [SerializeField] WheelCollider frontLeft;
    [SerializeField] WheelCollider backRight;
    [SerializeField] WheelCollider backLeft;

    [SerializeField] Transform frontRightTransform;
    [SerializeField] Transform frontLeftTransform;
    [SerializeField] Transform backRightTransform;
    [SerializeField] Transform backLeftTransform;

    public float acceleration = 700f;
    public float breakingForce = 300f;
    public float maxTurnAngle = 15f;

    private float currentAcceleration = 0f;
    private float currentBreakForce = 0f;
    private float currentTurnAngle = 0f;

    public float idleBreakingForce = 100f;
    public float maxRPM = 100f;
    public AnimationCurve torqueCurve;

    void Awake()
    {

        //Looking for original Position
        originalPos = transform.position;

    }

    private void FixedUpdate() {

        //Forward & reverse acceleration from w and s keys (vertical axis) & Stopping after some time
        currentAcceleration = acceleration * Input.GetAxis("Vertical");

        //Pressing space --> giving currentBreakForce a value 
        if (Input.GetKey(KeyCode.Space))
        {
            currentBreakForce = breakingForce;
        }
        else
        {
            currentBreakForce = (Mathf.Abs(currentAcceleration) < 0.1f) ? idleBreakingForce : 0f;
        }

        //Pressing space --> giving currentBreakForce a value 
        /*if (Input.GetKey(KeyCode.Space))
            currentBreakForce = breakingForce;
        else
            currentBreakForce = 0f;
        */
        //Acceleration on front wheels
        /*frontRight.motorTorque = currentAcceleration;
        frontLeft.motorTorque = currentAcceleration;
        */
        //Acceleration on front wheels
        frontRight.motorTorque = currentAcceleration * torqueCurve.Evaluate(Mathf.Clamp01(Mathf.Abs(frontRight.rpm) / maxRPM));
        frontLeft.motorTorque = currentAcceleration * torqueCurve.Evaluate(Mathf.Clamp01(Mathf.Abs(frontRight.rpm) / maxRPM));

        frontRight.brakeTorque = currentBreakForce;
        frontLeft.brakeTorque = currentBreakForce;
        backRight.brakeTorque = currentBreakForce;
        backLeft.brakeTorque = currentBreakForce;

        //steering
        currentTurnAngle = maxTurnAngle * Input.GetAxis("Horizontal");
        frontLeft.steerAngle = currentTurnAngle;
        frontRight.steerAngle = currentTurnAngle;

        //Updating the meshes of the wheels
        UpdateWheel(frontLeft, frontLeftTransform);
        UpdateWheel(frontRight, frontRightTransform);
        UpdateWheel(backLeft, backLeftTransform);
        UpdateWheel(backRight, backRightTransform);

    }
    void UpdateWheel(WheelCollider col, Transform trans) {

        //Get state of wheel collider
        Vector3 position;
        Quaternion rotation;
        col.GetWorldPose(out position, out rotation);

        // Set wheel mesh state
        trans.position = position;
        trans.rotation = rotation;

    }
    void Update()
    {
        //Reset Position and Rotation
        if (Input.GetKey("b"))
        {

            transform.position = originalPos;
            transform.localEulerAngles = new Vector3 (0, 90, 0);
        }

    }
}