How would I increase the friction of a car so that it doesn't glide when I don't give it any inputs?

Viewed 75

everyone. I am new to Unity 2D and C# and I was wondering how I could stop my car from gliding and sliding forward in my game when I don't want it to since it doesn't really feel like I am in control of my car if it's slipping so much. I would like it so if I don't give the car any inputs, or give counter inputs that the car almost immediately stops or starts moving the other way. I have tried creating a Physics2D material and increasing the friction but it really had no effect on the gameplay. I've also tried checking so that if there is no player inputs the rb.velocity is set to 0, or around .2 of what it currently is so it's a smoother stop but that only works if the player moves then lets go of the movement key, not if they try moving the opposite direction. I've also thought about checking which direction the car is moving by comparing a previous location with a current one then adding force in the opposite direction to stop the car but that seems very performance-intensive and I don't really know where I would start. If anyone has any suggestions for how I would go about doing this then please let me know how. This is the code I have so far:

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

public class CarController : MonoBehaviour
{

public Rigidbody2D carRigidbody;
public Rigidbody2D backTire;
public Rigidbody2D frontTire;

private float movement;
public float fspeed = 100;
public float bspeed = 60;
public float carTorque = 10;
public float decVel = .9f;
private bool beganMoving;



// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{
    movement = Input.GetAxis("Horizontal");
}

void FixedUpdate() {
    if (movement == 1 || movement == -1) {
        beganMoving = true;
    }
    if (movement == 0 && beganMoving) {
        backTire.velocity = new Vector2 (backTire.velocity.x * decVel * Time.fixedDeltaTime, backTire.velocity.y); 
        frontTire.velocity = new Vector2 (backTire.velocity.x * decVel * Time.fixedDeltaTime, backTire.velocity.y);
        
    }
    
    
    backTire.AddTorque(-movement * bspeed * Time.fixedDeltaTime);
    frontTire.AddTorque(-movement * fspeed * Time.fixedDeltaTime);
    carRigidbody.AddTorque(-movement * carTorque * Time.fixedDeltaTime);
}

}

2 Answers
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CarController : MonoBehaviour
{

public Rigidbody2D carRigidbody;
public Rigidbody2D backTire;
public Rigidbody2D frontTire;

private float movement;
public float fspeed = 100;
public float bspeed = 60;
public float carTorque = 10;
public float decVel = .9f;
private bool beganMoving;


// Update is called once per frame
void Update()
{
    movement = Input.GetAxis("Horizontal");
}

void FixedUpdate() {
    if (movement == 1 || movement == -1) {
        beganMoving = true;
    }
    if (movement <= 0.1f)
    {
        beganMoving = false;
    }
    if (movement <= 0.8f && beganMoving) // If the movement is starting to decrease and it the car has already started moving, set the velocities to zero.
    {
        backTire.velocity = Vector3.zero;
        frontTire.velocity = Vector3.zero;
    }
    if (movement == 0 && beganMoving) {
        backTire.velocity = new Vector2 (backTire.velocity.x * decVel * Time.fixedDeltaTime, backTire.velocity.y); 
        frontTire.velocity = new Vector2 (backTire.velocity.x * decVel * Time.fixedDeltaTime, backTire.velocity.y);
        
    }
    
    
    backTire.AddTorque(-movement * bspeed * Time.fixedDeltaTime);
    frontTire.AddTorque(-movement * fspeed * Time.fixedDeltaTime);
    carRigidbody.AddTorque(-movement * carTorque * Time.fixedDeltaTime);
}

Hi everyone browsing past this with similar issues. The way I solved this issue in the end was by implementing this whole chunk of code here:

isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, whatIsGround);

    if (movement == 1 || movement == -1) {
        beganMoving = true;
    } // this makes sure we've started moving which will be used later
    if (movement == 0 && isGrounded) {
        backTire.velocity = new Vector2 (backTire.velocity.x * .8f * Time.fixedDeltaTime, backTire.velocity.y); 
        frontTire.velocity = new Vector2 (frontTire.velocity.x * .8f * Time.fixedDeltaTime, frontTire.velocity.y);  // this whole if statement is so that our car will stop or decelerate when no input is given to it as to stop  it from rolling all across the ground
    }
    if (movement > 0 && prevMove < 0) { // checks if we are moving forward (right) when we used to move backwards (left)
        backTire.velocity = new Vector2 (backTire.velocity.x * decVel * Time.fixedDeltaTime, backTire.velocity.y); 
        frontTire.velocity = new Vector2 (frontTire.velocity.x * decVel * Time.fixedDeltaTime, frontTire.velocity.y); //stops us if the if statement returns true
        prevMove = 1; // sets our previous movement to moving forward to make it not repeat itself and to check with later on
    } else if (movement < 0 && prevMove > 0 ) { // checks if we are moving backwards when we used to be moving forwards
        backTire.velocity = new Vector2 (backTire.velocity.x * decVel * Time.fixedDeltaTime, backTire.velocity.y); 
        frontTire.velocity = new Vector2 (frontTire.velocity.x * decVel * Time.fixedDeltaTime, frontTire.velocity.y); //stops car
        prevMove = -1; // sets previous movement to moving backwards
    } else {
        if (beganMoving == true) { // when we start moving we set the previous movement to which ever direction we decided to first move in
        prevMove = movement;
        beganMoving = false; // set began moving to false. This doesn't make sense logically since we did begin moving but it's so this if statement doesn't repeat itself again
        }
    }

I've included comments so you can hopefully understand what and why I did. I hope this helps anyone with similar issues.

Related