Car changes gear when button is held, but but goes back to the original gear if I let it go.

Back at it again. I have this transmission script, works fine it changes gears and gets the current gears gear ratio, but when I press “upshift”, as long as it’s held, it’s in the next gear, if I let go, it goes back in to the one in was before. I tried all the updates and GetButtons, but nothing works.
Here’s the script:

public enum TransmissionType { Manual, Automatic }
public TransmissionType transmissionType = TransmissionType.Manual;

public Gear[ ] gears;
public int firstGear;
public int currentGear;
public float curGearRatio;

// Start is called before the first frame update
void Start()
{
for (int i = 0; i < gears.Length; i++)
{
if (gears*.ratio == 0)*
{
firstGear = i + 1;
break;
}
}
}
// Update is called once per frame
void Update()
{
currentGear = Mathf.Clamp(firstGear, 0, gears.Length - 1);
if (transmissionType == TransmissionType.Manual)
{
if (Input.GetButton(“Upshift”))
{
currentGear++;
}
if (Input.GetButton(“Downshift”))
{
currentGear–;
}
}
curGearRatio = gears[currentGear].ratio;
}
[System.Serializable]
public class Gear
{
public float ratio;
}

Do remember to use code tags. It makes the code more readable and easier to reference into when providing answers.

In this case, the answer seems pretty straightforward. However, rather than simply tell you what I think the answer is, what have you done to try and discover the actual cause of the problem? (Note: this is distinct from the question “what solutions have you tried?”).

For example, you could consider the use of Debug.Log statements. Though if you have a debugger, that might be more helpful. In a debugger, if you step through the Update method, what happens to the gear the player is in? Can you see why the code may give the result you are seeing?

Also, try to make class variables private. This is standard OO practise and can be helpful when debugging- for example, having a single locality in code (the class in this case) setting these values, limits the number of places to begin investigating when tracking down rogue values.

Moreover, you could consider putting member variables at the end of the class, not at the beginning. Whilst this makes no difference to compilation or runtime of code, it may help focus more on the interface of the class rather than its internal data stores- particularly when creating a new class. The usage of a class is often far more important than the implementation.

1 Like

Your Mathf.Clamp is wrong, you are using firstGear there which is never changed so it is resetting currentGear.