AppleyAppley Docs
Docs/Physics

Vehicles

Create drivable vehicles with wheel colliders and realistic physics.

24 min read Intermediate Updated 2026-07-01 v2.0 ~83 min to complete

Introduction

Vehicle physics is one of the most complex physics systems. This guide covers wheel colliders, steering, engine force, suspension, and anti-roll stabilization.

Guide 13 of 25

This is part of the Intermediate Guides collection. Category: Physics. Estimated completion: 83 minutes. Difficulty: Intermediate.

Screenshot

Vehicles
Vehicles

Step-by-Step Guide

1

Create the car body

Add a box rigidbody for the chassis. Set mass (800-1500 kg) and a box collider.

2

Add wheel colliders

Attach 4 Wheel Colliders at wheel positions. Set radius (0.3-0.4m), suspension distance, and spring/damper.

3

Configure suspension

Set spring (35000), damper (4500), target position (0.5). Determines bump reaction.

4

Implement steering

Set front wheel steer angle based on input. Use Ackermann steering for realistic turns.

5

Apply engine force

Apply motor torque to drive wheels. Use a gear curve: low gears = high torque, high = high speed.

6

Add anti-roll bars

Stabilize the car by applying opposing forces to left/right wheels. Prevents flipping.

FluxScript Example

Here is a complete FluxScript implementation for this guide:

Vehicles — FluxScript
on start {
  car = scene.find("RaceCar")
  car.setRigidbody(true)
  car.setMass(1200)
  car.setCollider("box", { size: vec3(2, 0.5, 4) })
  car.setCenterOfMass(vec3(0, -0.3, 0))
  wheelPos = [vec3(-1,0,1.4), vec3(1,0,1.4), vec3(-1,0,-1.4), vec3(1,0,-1.4)]
  for i = 0 to 4 {
    car.addWheel(wheelPos[i], { radius: 0.35, suspensionSpring: 35000, friction: 1.8 })
  }
}

on update(dt) {
  car = scene.find("RaceCar")
  speed = car.getSpeed()
  steerFactor = math.clamp(1 - speed / 80, 0.3, 1.0)
  steer = 0
  if input("a") steer = -25 * steerFactor
  if input("d") steer = 25 * steerFactor
  car.setWheelSteer(0, steer)
  car.setWheelSteer(1, steer)
  motor = 0
  if input("w") motor = 800
  if input("s") motor = -400
  car.setWheelMotor(2, motor)
  car.setWheelMotor(3, motor)
  if input("space") {
    for i = 0 to 4 car.setWheelBrake(i, 3000)
  } else {
    for i = 0 to 4 car.setWheelBrake(i, 0)
  }
}

Node Graph Example

Prefer visual programming? Here is the equivalent Node Graph:

Vehicles — Node Graph
[On Start] --> [Set Rigidbody: mass=1200, CoM low]
   --> [Add 4 Wheels: radius=0.35, suspension springs]

[On Update] --> [Get Speed] --> [Calculate steerFactor]
   --> [Set Steer: front wheels (speed-scaled)]
   --> [Set Motor: rear wheels]
   --> [Branch: braking] --> [Set Brake: all/none]

Optimization Tips

Keep your implementation fast and efficient with these optimization tips:

  • Lower the center of mass to prevent flipping. Set CoM 0.2-0.4m below chassis center.
  • Reduce steering angle at high speed. Full steering at 150km/h causes spins. Scale inversely with speed.
  • Limit physics substeps for vehicles (8-12) for stable wheel simulation. Regular physics needs only 4-6.
  • Use anti-roll bars on both axles. Without them, cars flip easily in turns.

Common Mistakes

Car flips on turns

Lower the center of mass and add anti-roll bars. Default CoM is too high for stable cornering.

Wheels sink through ground

Set correct wheel radius and suspension rest length. Mismatched values cause clipping.