I am working on a Unity 3D car controller, and everything is looking good except for when I reverse. When I try to steer when reversing, if I steer in one direction for too long, the car will spin out about 180 degrees. I have tried to fix this, but none of my solutions are working. Attached below is my code:
using UnityEngine;
public class CarControl : MonoBehaviour
{
public float motorTorque = 2000;
public float brakeTorque = 2000;
public float maxSpeed = 20;
public float maxReverseSpeed = 10;
public float steeringRange = 30;
public float steeringRangeAtMaxSpeed = 10;
public float velocityThreshold = 0.1f;
public float centreOfGravityOffset = -1f;
WheelControl[] wheels;
Rigidbody rb;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
// Adjust center of mass vertically, to help prevent the car from rolling
rb.centerOfMass += Vector3.up * centreOfGravityOffset;
// Find all child GameObjects that have the WheelControl script attached
wheels = GetComponentsInChildren<WheelControl>();
}
// Update is called once per frame
void Update()
{
float speedFactor;
float currentSteerRange;
float vertical = Input.GetAxis("Vertical");
float horizontal = Input.GetAxis("Horizontal");
// Calculate current speed in relation to the forward direction of the car
// (this returns a negative number when traveling backwards)
float forwardSpeed = Vector3.Dot(transform.forward, rb.velocity);
// Calculate how close the car is to top speed
// as a number from zero to one
speedFactor = Mathf.InverseLerp(0, maxSpeed, forwardSpeed);
// Use that to calculate how much torque is available
// (zero torque at top speed, b/c car is at the max speed so no more torque should be there)
float currentMotorTorque = Mathf.Lerp(motorTorque, 0, speedFactor);
// and to calculate how much to steer
// (the car steers more gently at top speed)
currentSteerRange = Mathf.Lerp(steeringRange, steeringRangeAtMaxSpeed, speedFactor);
// Check whether the user input is in the same direction
// as the car's velocity
bool isAccelerating = Mathf.Sign(vertical) == Mathf.Sign(forwardSpeed);
foreach (var wheel in wheels)
{
// Apply steering to Wheel colliders that have "Steerable" enabled
if (wheel.steerable)
{
wheel.WheelCollider.steerAngle = horizontal * currentSteerRange;
}
if (isAccelerating)
{
// Apply torque to Wheel colliders that have "Motorized" enabled
if (wheel.motorized)
{
wheel.WheelCollider.motorTorque = vertical * currentMotorTorque;
}
wheel.WheelCollider.brakeTorque = 0;
}
else
{
// If the user is trying to go in the opposite direction
// apply brakes to all wheels
wheel.WheelCollider.brakeTorque = Mathf.Abs(vertical) * brakeTorque;
wheel.WheelCollider.motorTorque = 0;
}
if(Input.GetKey(KeyCode.Space))
{
wheel.WheelCollider.brakeTorque += brakeTorque;
}
}
}
}