- 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