- Home /
Car Gearbox script
Hi, i'm making a racing game, and i made a car controller script. It works well but i want to add an automatic gearbox to it. How do i do it ?
PS : i want it to shift according to the engine RPM (for example if the engine reaches 100 RPM it switches to second speed) and i want to be able to edit the number of speeds (all the cars in the game doesn't have the same amount of speeds)
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
public enum Axel
{
Front,
Middle,
Rear
}
public enum driveType
{
frontWheelDrive,
rearWheelDrive,
allWheelDrive
}
[Serializable]
public struct Wheel
{
public GameObject model;
public WheelCollider collider;
public Axel axel;
}
public enum drivetype
{
allWheelDrive = 1, rearWheelDrive = 2, frontWheelDrive = 3
}
[RequireComponent(typeof(InputManager))]
public class PlayerCarController : MonoBehaviour
{
public driveType DriveType;
public InputManager inputManager;
public List<Wheel> wheels;
public Rigidbody localRigidbody;
public Vector3 centerOfMass;
//Throttle System variables
public float torque = 1000f;
public float maxAcceleration = 20f;
public float finalMaxAcceleration;
public float currentSpeed;
public float topSpeed /*= 200f*/;
public float topSpeedValue = 200;
//Steering system variables
public float turnSensitivity = 1f;
public float maximumTurnAngle = 45f;
//Hand brake system variables
public bool handBrakeIsOn;
//nitro system variables
public bool nitroIsOn;
public float nitroValue = 1;
void Start()
{
localRigidbody = GetComponent<Rigidbody>();
localRigidbody.centerOfMass = centerOfMass;
}
private void Update()
{
finalMaxAcceleration = maxAcceleration * nitroValue;
currentSpeed = localRigidbody.velocity.sqrMagnitude;
//Debug.Log(currentSpeed + " | " + topSpeed);
}
void FixedUpdate()
{
AnimateWheels();
ThrottleSystem();
SteeringSystem();
HandBeakeSystem();
NitroSystem();
TopSpeedDefinition();
}
void ThrottleSystem()
{
foreach (var wheel in wheels)
{
if (DriveType == driveType.allWheelDrive)
{
wheel.collider.motorTorque = inputManager.throttle * finalMaxAcceleration * torque * Time.deltaTime;
}
if (DriveType == driveType.rearWheelDrive)
{
if(wheel.axel == Axel.Rear)
{
wheel.collider.motorTorque = inputManager.throttle * finalMaxAcceleration * torque * Time.deltaTime;
}
}
if (DriveType == driveType.frontWheelDrive)
{
if (wheel.axel == Axel.Front)
{
wheel.collider.motorTorque = inputManager.throttle * finalMaxAcceleration * torque * Time.deltaTime;
}
}
}
}
void TopSpeedDefinition()
{
foreach (var wheel in wheels)
{
if (currentSpeed > topSpeed)
{
wheel.collider.motorTorque = 0f;
}
else if (currentSpeed < topSpeed)
{
wheel.collider.motorTorque = inputManager.throttle * finalMaxAcceleration * torque * Time.deltaTime;
}
}
}
void SteeringSystem()
{
foreach (var wheel in wheels)
{
if (wheel.axel == Axel.Front)
{
var _steerAngle = inputManager.steer * turnSensitivity * maximumTurnAngle;
wheel.collider.steerAngle = Mathf.Lerp(wheel.collider.steerAngle, _steerAngle, 0.5f);
}
}
}
void HandBeakeSystem()
{
if (inputManager.handBrake)
{
handBrakeIsOn = true;
}
else
{
handBrakeIsOn = false;
}
foreach (var wheel in wheels)
{
if(handBrakeIsOn == true)
{
wheel.collider.brakeTorque = 1000000000f;
wheel.collider.motorTorque = 0f;
}
else if(handBrakeIsOn == false)
{
wheel.collider.brakeTorque = 0f;
wheel.collider.motorTorque = inputManager.throttle * finalMaxAcceleration * torque * Time.deltaTime;
}
}
}
void NitroSystem()
{
if(inputManager.nitro)
{
nitroIsOn = true;
}
else
{
nitroIsOn = false;
}
if(nitroIsOn == true)
{
nitroValue = 5f;
topSpeed = topSpeedValue * 2f;
}
else if (nitroIsOn == false)
{
nitroValue = 1f;
topSpeed = topSpeedValue;
}
}
void AnimateWheels()
{
foreach (var wheel in wheels)
{
Vector3 wheelColliderPosition;
Quaternion WheelColliderRotation;
wheel.collider.GetWorldPose(out wheelColliderPosition, out WheelColliderRotation);
wheel.model.transform.position = wheelColliderPosition;
wheel.model.transform.rotation = WheelColliderRotation;
}
}
}
Answer by Ludio33 · Dec 30, 2020 at 04:24 PM
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
// The RPMs
public int RPM;
public int MaxRPM;
public int ChangeRPM;
// This is the actual GearBox
public float[] Gearbox;
public int CurrentGear;
public bool CanShiftGear = false;
// The vehicle Speed
public float Speed;
public Rigidbody RB;
public float Torque;
private void Update()
{
// It checks if the RPMs are the desired ones and if you can shift
// UpShift
if (RPM >= ChangeRPM && CanShiftGear && CurrentGear != Gearbox.Length -1)
{ CurrentGear++; CanShiftGear = false; }
//DownShift
if(RPM <= 2000f && CanShiftGear && CurrentGear != 0)
{ CurrentGear--; CanShiftGear = false; }
// Takes Car Of the boolean
if(RPM < ChangeRPM)
{ CanShiftGear = true; }
// Once you have reached the last gear ypu can not shift
if(CurrentGear == Gearbox.Length -1)
{ CanShiftGear = false; }
// Speed
Speed = RB.velocity.magnitude;
GearBox();
}
void GearBox()
{
if(Speed >= Gearbox[CurrentGear])
{ Torque = 0f; }
else
{ Torque = 1f; }
}
}
This should work. For the Top Speed just go into the inspector and edit the size and floats of the GearBox[] and fill each gap with wathever top speed you want in that gear. Also for the RPMs of the car I would recommed smoething like the WheelsCollider.rpm
I think for manual you just have to do :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
// The RPMs
public int RPM;
public int MaxRPM;
public int ChangeRPM;
// This is the actual GearBox
public float[] Gearbox;
public int CurrentGear;
public bool CanShiftGear = false;
// The vehicle Speed
public float Speed;
public Rigidbody RB;
public float Torque;
private void Update()
{
// It checks if the RPMs are the desired ones and if you can shift
// UpShift
if (RPM >= ChangeRPM && CanShiftGear && CurrentGear != Gearbox.Length -1)
{ CurrentGear++; CanShiftGear = false; }
//DownShift
if(RPM <= 2000f && CanShiftGear && CurrentGear != 0)
{ CurrentGear--; CanShiftGear = false; }
// Takes Car Of the boolean
if(RPM < ChangeRPM)
{ CanShiftGear = true; }
// Once you have reached the last gear ypu can not shift
if(CurrentGear == Gearbox.Length -1)
{ CanShiftGear = false; }
// Speed
Speed = RB.velocity.magnitude;
if Input.GetKeyDown(KeyCode.G)
{
GearBox();
}
}
void GearBox()
{
if(Speed >= Gearbox[CurrentGear])
{ Torque = 0f; }
else
{ Torque = 1f; }
}
}
NOTE : You have to press "G" to change gears.
Your answer
Follow this Question
Related Questions
Better RPM?? 0 Answers
transmission clutch help! 1 Answer
A game like Need For Speed? 1 Answer
Engine animation curve 1 Answer
Car shifting effect? Help please! 1 Answer