Skip to content

Instantly share code, notes, and snippets.

@victorbstan
Last active September 11, 2023 05:29
Show Gist options
  • Save victorbstan/e5903829576eaf6ce5e3 to your computer and use it in GitHub Desktop.
Save victorbstan/e5903829576eaf6ce5e3 to your computer and use it in GitHub Desktop.
Unity car simulation script
using UnityEngine;
using System.Collections;
public class CarControl : MonoBehaviour {
// NOTE: Companion script for wheel suspensions, attach to each wheel.
// https://gist.github.com/victorbstan/4dde0d0b4203c248423e
// PUBLIC
public bool driveable = false;
// Wheel Wrapping Objects
public Transform frontLeftWheelWrapper;
public Transform frontRightWheelWrapper;
public Transform rearLeftWheelWrapper;
public Transform rearRightWheelWrapper;
// Wheel Meshes
// Front
public Transform frontLeftWheelMesh;
public Transform frontRightWheelMesh;
// Rear
public Transform rearLeftWheelMesh;
public Transform rearRightWheelMesh;
// Wheel Colliders
// Front
public WheelCollider wheelFL;
public WheelCollider wheelFR;
// Rear
public WheelCollider wheelRL;
public WheelCollider wheelRR;
public float maxTorque = 20f;
public float brakeTorque = 100f;
// max wheel turn angle;
public float maxWheelTurnAngle = 30f; // degrees
// car's center of mass
public Vector3 centerOfMass = new Vector3(0f, 0f, 0f); // unchanged
// GUI
//...
public float RO_speed; // READ ONLY (Debug)
public float RO_EngineTorque; // READ ONLY (Debug)
public float RO_SteeringAngleFL; // READ ONLY (Debug)
public float RO_SteeringAngleFR; // READ ONLY (Debug)
public float RO_BrakeTorque; // READ ONLY (Debug)
// PRIVATE
// acceleration increment counter
private float torquePower = 0f;
// turn increment counter
private float steerAngle = 0f;
// original wheel positions
// Front Left
private float wheelMeshWrapperFLx;
private float wheelMeshWrapperFLy;
private float wheelMeshWrapperFLz;
// Front Right
private float wheelMeshWrapperFRx;
private float wheelMeshWrapperFRy;
private float wheelMeshWrapperFRz;
// Rear Left
private float wheelMeshWrapperRLx;
private float wheelMeshWrapperRLy;
private float wheelMeshWrapperRLz;
// Rear Right
private float wheelMeshWrapperRRx;
private float wheelMeshWrapperRRy;
private float wheelMeshWrapperRRz;
void Start () {
rigidbody.centerOfMass = centerOfMass;
// Setup initial values
// Front Left
// wheelMeshWrapperFLx = frontLeftWheelWrapper.localPosition.x;
// wheelMeshWrapperFLy = frontLeftWheelWrapper.localPosition.y;
// wheelMeshWrapperFLz = frontLeftWheelWrapper.localPosition.z;
// Front Right
// wheelMeshWrapperFRx = frontRightWheelWrapper.localPosition.x;
// wheelMeshWrapperFRy = frontRightWheelWrapper.localPosition.y;
// wheelMeshWrapperFRz = frontRightWheelWrapper.localPosition.z;
// Rear Left
// wheelMeshWrapperRLx = rearLeftWheelWrapper.localPosition.x;
// wheelMeshWrapperRLy = rearLeftWheelWrapper.localPosition.y;
// wheelMeshWrapperRLz = rearLeftWheelWrapper.localPosition.z;
// Rear Right
// wheelMeshWrapperRRx = rearRightWheelWrapper.localPosition.x;
// wheelMeshWrapperRRy = rearRightWheelWrapper.localPosition.y;
// wheelMeshWrapperRRz = rearRightWheelWrapper.localPosition.z;
}
// Visual updates
void Update () {
if (! driveable) {
return;
}
// SETUP WHEEL MESHES
// Turn the mesh wheels
frontLeftWheelWrapper.localEulerAngles = new Vector3(0, steerAngle, 0);
frontRightWheelWrapper.localEulerAngles = new Vector3(0, steerAngle, 0);
// Wheel rotation
frontLeftWheelMesh.Rotate(0, wheelFL.rpm / 60 * 360 * Time.deltaTime, 0);
frontRightWheelMesh.Rotate(0, wheelFR.rpm / 60 * 360 * Time.deltaTime, 0);
rearLeftWheelMesh.Rotate(0, wheelRL.rpm / 60 * 360 * Time.deltaTime, 0);
rearRightWheelMesh.Rotate(0, wheelRR.rpm / 60 * 360 * Time.deltaTime, 0);
// Audio
audio.pitch = (torquePower / maxTorque) + 0.5f;
}
// Physics updates
void FixedUpdate () {
if (! driveable) {
return;
}
// CONTROLS - FORWARD & RearWARD
if ( Input.GetKey(KeyCode.Space) ) {
// BRAKE
torquePower = 0f;
wheelRL.brakeTorque = brakeTorque;
wheelRR.brakeTorque = brakeTorque;
} else {
// SPEED
torquePower = maxTorque * Mathf.Clamp( Input.GetAxis("Vertical"), -1, 1 );
wheelRL.brakeTorque = 0f;
wheelRR.brakeTorque = 0f;
}
// Apply torque
wheelRR.motorTorque = torquePower;
wheelRL.motorTorque = torquePower;
// Debug.Log(Input.GetAxis("Vertical"));
Debug.Log("torquePower: " + torquePower);
Debug.Log("brakeTorque RL: " + wheelRL.brakeTorque);
Debug.Log("brakeTorque RR: " + wheelRR.brakeTorque);
Debug.Log("steerAngle: " + steerAngle);
// CONTROLS - LEFT & RIGHT
// apply steering to front wheels
steerAngle = maxWheelTurnAngle * Input.GetAxis("Horizontal");
wheelFL.steerAngle = steerAngle;
wheelFR.steerAngle = steerAngle;
// Debug info
RO_BrakeTorque = wheelRL.brakeTorque;
RO_SteeringAngleFL = wheelFL.steerAngle;
RO_SteeringAngleFR = wheelFR.steerAngle;
RO_EngineTorque = torquePower;
// SPEED
// debug info
RO_speed = rigidbody.velocity.magnitude;
// KEYBOARD INPUT
// FORWARD
if ( Input.GetKey(KeyCode.W) ) {
// Debug.Log("FORWARD");
}
// BACKWARD
if ( Input.GetKey(KeyCode.S) ) {
// Debug.Log("BACKWARD");
}
// LEFT
if ( Input.GetKey(KeyCode.A) ) {
// Debug.Log("LEFT");
}
// RIGHT
if ( Input.GetKey(KeyCode.D) ) {
// Debug.Log("RIGHT");
}
// BRAKE
if ( Input.GetKey(KeyCode.Space) ) {
// Debug.Log("SPACE");
}
}
}
@KarloRomic
Copy link

how to increase the speed when turning? as fast as when moving forward

If you mean steering wheel (and wheels) then change
public float maxWheelTurnAngle = 30f; // degrees
If you mean response time, then i would recommend putting all of the if statements that check for keypresses
Input.GetKey(KeyCode.W) to the Update function so that you catch every key press precisely at time.
If you mean steering with more grip (faster steering) and less sliding, then try this wheel configurations for every wheel colider:
Forward friction: 2, 5, 5, 2, 1
Also try changing values of the Sideways friction and see the results, try playing with the Sideways friction setting on your wheel coliders, the best way to do it is while you are in play mode.

@Charmscobb
Copy link

My car gets sent flying into the air, how do i fix this?

@RJAmoto
Copy link

RJAmoto commented Sep 21, 2021

I want to change the controls to a screen button, how can I convert this to a button input, for example I press gas button and it will move forward, what function makes it move forward when w is pressed and what function makes it go left and right when a and d is pressed, the getKeycode function has nothing inside...

@RagaSaga
Copy link

Hello everyone! I don't know why I am getting the following issue whenever I am entering play mode after assigning the scrip to my car: -
" ArgumentNullException: Value cannot be null.
Parameter name: source UnityEngine.AudioSource.set_pitch (System.Single value) (at <7117d168a9ec4e518e0de7d9c98bd09a>:0)
CarMovement.Update () (at Assets/Scripts/CarMovement.cs:125) "

I cannot find any fix for it (I am a beginner). I have assigned the desired objects to every variable slot. Please Help.
Just to be informed I am using this ( https://assetstore.unity.com/packages/3d/vehicles/land/free-sci-fi-car-184607 ) car for my project and have assigned the wheel colliders to its wheels.

Please Help.

@Erwin-afk
Copy link

My car gets sent flying into the air, how do i fix this?

Add rigidbody to it.

@NithinBODDU
Copy link

What do you mean by "Wheel Wrapper"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment