REALISTIC CAR PHYSICS
Aug 27, 2025 - Solo Project - Unity C#
Aug 27, 2025 - Solo Project - Unity C#
Implement suspension using Hooke's law, add damping
Implement Ackermann steering
Calculate the lateral slip angle
Plot the slip angle on the slip angle curve, gives the cornering force
Apply cornering force, take into account the torque on the car body
Each tick, the water propagates outwards with speed depending on the unit type ( forest, concrete ) under it
Therefore, water travels faster over concrete than over nature
Water can only spread to a unit where the land height is lesser than the water height ( on that x, y )
The WaterManager has a reference to the heightmap of the LandManager, but not the LandManager directly, this facilitates interchangeability between classes ( fast and SOLID )
MOTIVATION
I wanted to make a racing game. Unity's standard WheelCollider was not cutting it. Good assets were often pricey or closed source.Â
In order to expand my knowledge, I decided to delve into the physics behind cars.
RESEARCH
I wanted to make a racing game. Unity's standard WheelCollider was not cutting it. Good assets were often pricey or closed source.Â
In order to expand my knowledge, I decided to delve into the physics behind cars.
JITTERING BUG
With the old system, if I increase the grip or ride height of the car, the car would violently shake and jitter around.Â
This was because the calculation for the friction force was not implemented using the aforementioned lateral slip angle curve.
FORWARD MOTION
The image on the left was my test scene for forward motion. The lines of the wheel perfectly align with the texture on the ground.Â
This allowed me to perfectly see if there was a difference between rotation of the wheel and motion of the car.
☆ First, the "space" of the velocity is changed to suit the formulas. Then, the current rollHeight is calculated so that the slip angle is accurate. Finally, the slip angle is calculated by comparison the wheel direction to the car velocity.
☆ GetNormalizedLateralForce(slipAngle) is the function that has the slip angle curve in it. Changing this curve changes the "feel" of the tire. It's normalized because it must be multiplied by the downforce, which in this case is the force the suspension is applying ground.
The values carSpeed and stopSpeed are required to make the car come to a complete stop, this is because the friction force calculation becomes more inaccurate the lesser lateral velocity of the car gets.
☆ Here, the total friction output the wheel can muster is limited. This is required because the wheel can't, for example, accelerate and turn at the same time. This effect can be achieved with an ellipse whereby the forward friction is favored over the lateral.Â
    public interface ICarInput
    {
        float gas { get; }
        float steering { get; }
        float brake { get; }
        bool forwardDrive { get; }
    }
☆ This is my interface that allows me to dynamically assign an input method to the car.
<--