# [TUTORIAL] How to get a car working on Unity 5

Discussion in 'Physics' started by SnakeTheRipper, Jul 29, 2015.

1. ### SnakeTheRipper

Joined:
Dec 31, 2014
Posts:
136
Hi everybody ! I had problems with Unity 5 and cars for a long time but I managed to get a working car pretty good with 6 gears and a top speed of 260 km/h.

If any of you want to achieve this, you should :

• Use a real-scale car model (if it's too little or too big it works badly, this is very IMPORTANT)
• Apply around 1000-1500 kg of mass to the car rigidbody
• Apply around 60 kg of mass to each wheel
• For all wheels, default WheelCollider values for forward friction except stiffness to 2.
• For all wheels, default WheeCollider values for sideways friction.

Once you have this setup, you are ready to apply your equations and make the input control the car.

The basics of using RPM and gears need a pair of animation curves and some equations to work.

The RPM curve should look like this (for a high-end car) :

The Gear curve should look like this :

You can slightly modify those to match your desired settings.

Once you have all this ready, in your equations you should take in mind those curves and evaluate the value depending on the current RPM and the current Gear.

Code (CSharp):
1. float WheelsRPM = (backRightWheel.rpm + backLeftWheel.rpm) / 2f;
2.
3. float currentRPM = MinRPM + (WheelsRPM * FinalDriveRatio * GearCurve.Evaluate(currentGear));
On the first part you want to get the wheel RPMs as accurate as possible, so I will take both rpm from the back wheels and make the arithmetic mean.

Then, to calculate the current RPM we will need to sum up the minimum RPM for our car (in my case I have 1000 as minimum) to the formula.

This formula takes the Wheels RPM we calculated before and multiplies it by the Final Drive Ratio (in my case I have 4) and multiplies it by value depending on the gear (calculated from the gear curve).

Once you have the RPM formulas set up, we need the last formula.

Code (CSharp):
1. float currentTorque = RPMCurve.Evaluate(currentRPM) * GearCurve.Evaluate(currentGear) * FinalDriveRatio * Input.GetAxis("Vertical");
So, in this formula, we'll take in it the current RPM value we calculated before and evaluate it on the RPM curve. This value will be multiplied again by the evaluation of the current gear in the gear curve and by the final drive ratio.

Lastly, we'll multiply it by the Input so it will only accelerate if you are pressing the input.

With all this calculated, we will now need to apply the torque to the back wheels. We'll do that diving the torque by 2 and then applying it to the back left and right wheels. We divide it by 2 beacuse each wheel will get half of the torque. If we do an AWD car, we will divide it by 4 and apply the torque to all wheels.

With this all set, you have the basics ready. Now for the last part you need to implement the braking system, which should be relatively easy (when moving, instead of applying inverse motorTorque, you apply 0 motorTorque and some amount of brakeTorque to each wheel).

You'll also need to add the gear system which is relatively easy and I'll explain someday here too, but basically when your RPMs are above x value (for me 8400) I switch to a bigger gear. The gear switch has a delay of 0.6 and some sound effects.

I hope you get it working guys, I know it's really frustrating because I've been there, but once you get it to work, you get a moral boost!

Last edited: Jul 29, 2015
2. ### RLin

Joined:
May 10, 2015
Posts:
110
@SnakeTheRipper, great job! However, I have to disagree with you on some things:
1. Apply 1000-1500 kg of mass to the rigidbody.
I use real world values for my vehicles, and some go over 2000 kg. They need some suspension tweaking but otherwise work fine.
2. Forward friction stiffness of 2.
This is simply too much grip for a realistic vehicle. I have tried it before, and even a 2000 kg minivan can have a 0-62 time in about one second without losing any grip. Braking is also too powerful; real world cars have their wheels lock up when slamming the brakes without ABS. That in mind, I gave the wheels enough brake torque to lock the wheels. The brakes were so powerful that instead of skidding, the car just immediately stopped and did a handstand on its front wheels before tipping on its roof.

3. ### SnakeTheRipper

Joined:
Dec 31, 2014
Posts:
136
Well if you want a race car it won't go over 2000kg. Also the high forward friction stiffnes is to avoid skidding on the first gear when accelerating due to the high torque.

4. ### RLin

Joined:
May 10, 2015
Posts:
110
I was talking about cars in general often go over 1500 kg. I am making a need for speed style game, and some of the sedans exceed 1650 kg. To avoid skidding, I just increased wheelcollider mass to about 100 and found the balance between more torque for more wheelcollider rpms and less torque for avoiding crazy skids.

SnakeTheRipper likes this.
5. ### RLin

Joined:
May 10, 2015
Posts:
110
200 km/h is pretty slow for a race car. My 1600 kg sedan (which although unlicensed, has suspiciously similar stats and appearance to a Mitsubishi Lancer Evolution X), tops out at about 250 km/h, and that is one of the slowest cars in my game. How fast do your vehicles go 0-100 km/h?

6. ### SnakeTheRipper

Joined:
Dec 31, 2014
Posts:
136
Oops sorry I misswrote that. It reaches 260km/h and stops there at gear 6. It goes 0-100 in about 4-5 seconds.

7. ### RLin

Joined:
May 10, 2015
Posts:
110
What sort of racing game are you making?

8. ### SnakeTheRipper

Joined:
Dec 31, 2014
Posts:
136
For now I'm just trying to achieve a good and fun car driving system. Maybe I'll go for an arcade game for android, most probably.

9. ### RLin

Joined:
May 10, 2015
Posts:
110
If you want arcade, wheelcolliders are not the way to go. Also, wheelcolliders seem to have poor performance on mobiles, unless you use very few of them and heavily optimize everything else.

10. ### SnakeTheRipper

Joined:
Dec 31, 2014
Posts:
136
Huh yeah the first versions I've tried on mobile show a very poor performance. After lowering all settings and optimizing a bit of code I've managed to get a good framerate but not as good as I wanted.

Thanks for the tip !