UDN
Search public documentation

VehiclesTechnicalGuide
Licensees can log in.

Red links require licensee log in.

Interested in the Unreal engine?
Check out the licensing page.

Questions about UDN itself?
Contact the UDN Staff

Vehicle System Technical Guide

Document Summary: A technical guide to the vehicle system in Unreal Engine 3.

Document Changelog: Created and updated by James Golding.

Overview

The vehicle system in UnrealEngine 3 utilizes the rigid body physics engine and should allow you to create a large variety of different vehicles - from wheeled cars to tanks, to turrets and vehicles that hover or fly. This document gives an overview of the system, including what the parameters do.

Vehicle Classes

Vehicle

This is the base class for all vehicles. It contains the basic control inputs Steering, Throttle and Rise, as well as the stubs for much of the AI code that is used to allow computer players to drive vehicles. It also includes the code used for getting in and out of vehicles. You would probably want to subclass this to create something like a fixed turret.

SVehicle

This is the base class for vehicles that use physics. It contains all the parameters for supporting wheeled vehicles.

SimObj The SVehicleSimBase object that handles much of the vehicle simulation. More on this below.
Wheels The array of SVehicleWheel objects, holding parameters for each wheel (in the case of a wheeled vehicle).
COMOffset Center Of Mass location of the vehicle, in local space.
InertiaTensorMultiplier This scales the inertia tensor for the vehicle. This affects how easy the vehicle is to spin around each axis, it’s the angular equivalent of mass.
MaxSpeed Vehicle speed is capped to this value.
bUseSuspensionAxis If TRUE, then the wheel contact with the ground will always have its normal point back along the suspension axis. If FALSE, the wheel contact will use the surface normal of the ground it hits.

There are a number of `output' parameters in the SVehicle class that you can use elsewhere in your code.

bVehicleOnGround True if any SVehicleWheel is currently touching the ground (ignores contacts with chassis etc).
TimeOffGround Time that bVehicleOnGround has been false for.
bVehicleOnWater True if any SVehicleWheel is currently touching water
bIsInverted True if vehicle is mostly upside down.
bChassisTouchingGround True if there are any contacts between the chassis of the vehicle and the ground.
bWasChassisTouchingGroundLastTick True if there were any contacts between the chassis of the vehicle and the ground last tick.
SVehicle also contains support for an `upright constraint'. This is a springy constraint that is used to keep the vehicle upright as it moves around, and can be useful for certain sorts of hover vehicles.

bStayUpright Use the stay-upright world constraint.
StayUprightRollResistAngle Angle at which the vehicle will resist rolling.
StayUprightPitchResistAngle Angle at which the vehicle will resist pitching.
StayUprightStiffness Stiffness of upright spring past the limit angles.
StayUprightDamping Damping of upright spring past the limit angles.

If a vehicle does get flipped, SVehicle has support for being flipped back over again using the following settings

bCanFlip True if vehicle can be uprighted by player.
UprightLiftStrength Scales the lifting force applied to the vehicle during uprighting.
UprightTorqueStrength Scales the torque applied to the vehicle during uprighting.
UprightTime Time in seconds to apply uprighting force/torque.

SVehicleSimBase

Much of the simulation work for a vehicle is handled inside a SVehicleSimBase object. This is broken out as a separate object so that you can create a game-specific SVehicles-derived base class for all your vehicles, but still re-use code for different vehicle types.

WheelSuspensionStiffness Controls the stiffness of the suspension spring for the wheels. There is no particular range on this value, but we have used values between 20.0 and 500.0.
WheelSuspensionDamping Controls the damping of the suspension spring for the wheels. The larger this number, the less oscillation you will get on the suspension. Again, there is no particular range for this number, but we have used values between 1.0 and 75.0.
WheelSuspensionBias Offset applied to the equilibrium position for the wheel suspension.
WheelInertia The mass of the wheels. Used by PhysX to determine the wheel velocity that wheel torques can achieve. How 'heavy' and hard to turn the wheels are.
bWheelSpeedOverride If true, you can specify the speed of this wheel directly, rather than applying a torque and have the physics update the wheel speed accordingly. This is used by the SVehicleSimTank object, which calls setAxleSpeed on the wheel.

The Wheel Model

The UnrealEngine 3 vehicle system makes use of a Pacejka-like wheel model (you can find more on this type of model using Google). The wheel model is broken down into a lateral (sideways) direction and a longitudinal direction (in the direction of roll). For each direction there is a curve which relates the amount of slip between the wheel and the ground and the amount of force generated. The curve looks like this:

pacejka_curve.jpg

For the lateral direction Slip Angle is used as input and for the longitudinal direction Slip Ratio is used. The way you specify these curves is by giving the co-ordinates of the two points shown in the diagram, referred to as `Extremum' and `Asymtote'. The Extremum is the point of maximum force, where as Asymptote point gives the output value at infinite slip. The tangent at each point is taken as flat, and a cubic spline is fitted between them to give the final shape of the curve. The properties you use for each curve are defined as:

Wheel..ExtremumSlip The input Slip value of the Extremum point.
Wheel..ExtremumValue The output value of the Extremum point.
Wheel..AsymptoteSlip The input Slip value of the Asymptote point.
Wheel..AsymptoteValue The output value of the Asymptote point.

Early versions of the wheel simulation would increase the wheel force greatly when there was a large relative velocity between wheel and ground. This meant that landing jumps and sliding stably was quite hard. Later the ‘clamped friction mode’ was introduced which helped fix this. To use this model, set the ‘bClampedFrictionModel’ option in SVehicleSimBase to TRUE. Note that doing this on an existing vehicle will require re-tuning of the wheel paramters described above. The SVehicleSimBase class uses default wheel function values that should be a good starting point for an average wheeled vehicle.

SVehicleWheel

There are several values that are set on the SVehicleWheel by the simulation code each tick, and are then passed down into the physics.

Steer The steering angle of the wheel. 0 is straight ahead, positive angles steer to the right. In degrees.
MotorTorque The motor torque that should be applied to this wheel. Can be negative to motorise the wheel to spin backwards.
BrakeTorque Amount of brake torque to apply to wheel to prevent rotation. Should always be positive.
ChassisTorque Amount of torque to apply back to the chassis from this wheel, so that it pitches up when accelerating etc.

Many other parameters of the wheel are used by the simulation code to determine what the values above should be. These usually do not change over time.

bPoweredWheel If power should be applied to this wheel.
bHandbrakeWheel Whether the `handbrake' reduces grip on this wheel when applied.
SteerFactor How much this wheel should respond to steering. If 0, the wheel will not turn when steering. If 1.0, it will steer to the right when the steering does. Setting this to -1.0 will cause the wheel to steer in the opposite direction, which can be useful in 4-wheel steering configurations for example.
LongSlipFactor Per-wheel scaling of wheel force function defined in SVehicleSimBase in Longitudinal direction.
LatSlipFactor Per-wheel scaling of wheel force function defined in SVehicleSimBase in Latitudinal direction.
SkelControlName The name of the SkelControlWheel that should be updated based on this wheel. For more information, see the SettingUpVehicles document
BoneName The name of the bone in the skeletal mesh that is used to position the wheel.
BoneOffset Offset from the bone specified using BoneName to place the wheel at.
WheelRadius The radius of the wheel.
SuspensionTravel How much vertical travel the wheel is allowed before it hits the `hard' stop.
SuspensionSpeed To avoid the graphics wheel moving too quickly (eg when going up steps), you can specify the maximum number of Unreal unite per second the wheel can move.
WheelParticleSystem An optional particle system that is used to generate smoke effects for this wheel. A float parameter called `WheelSlip' is set on this particle system each tick which can be used to modify spawn rate etc.
Side Used for tank vehicles, to indicate if this wheel forms part of the left or right ‘tread’ of the vehicle.

The SVehicleWheel also provides a number of `output' parameters, which are updated each frame.

bWheelOnGround If this particular wheel is currently on the ground.
SpinVel The current angular velocity of this wheel, in radians per second.
LongSlipRatio Current longitudinal slip ratio for this wheel.
LatSlipAngle Current lateral slip angle for this wheel.
ContactNormal Direction of the contact normal between the wheel and the ground.
LongDirection Longitudinal wheel direction vector, in world space.
LatDirection Lateral wheel direction vector, in world space.
ContactForce Magnitude of force applied by this wheel last frame.
LongImpulse Size of impulse applied in the longitudinal direction last frame.
LatImpulse Size of impulse applied in the lateral direction last frame.
SuspensionPosition Current vertical displacement of the wheel on its suspension.
CurrentRotation Current rotation of the wheel, in degrees.

The line check done by the physics is then the suspension travel plus the wheel radius.

Different Types Of Vehicle

The various wheeled vehicle tools provided by the SVehicle class can create a large number of different vehicle types. It is well worth looking at Unreal Tournament 3 to see how some of them operate. Here are some non-traditional vehicle types:

Wheeled Vehicles

Wheeled vehicles in UnrealEngine 3 are simulated as a single rigid body. Ray-casts are made from points on the car chassis downwards to see where they hit the ground, and forces are computed at the contact point based on a number of parameters. There are no physical `wheel' objects - the engine just stores how fast each wheel is moving, and uses that in the calculations for forces generated.

Hover Vehicles

These are done by creating wheels with a long, soft suspension travel, and no wheel friction at all, allowing them to move in all direction. Then we just uses forces, torques and damping to control the movement of the vehicle.

Flying Vehicles

For vehicles like helicopters, where the vehicle stays upright, we use the StayUprightConstraint to gently keep the vehicle upright. Then by overriding the GetGravityZ() function, you can make the vehicle ‘hover’ and be easily driven with forces.

Tanks

UE3 contains an SVehicleSimTank object for this purpose.

With full throttle applied, the tank engine will split up the MaxEngineToque across both tracks. This will be an even split unless the tank is being steered. When steered, the torque will be split based on the InsideTrackTorqueCurve according to its current speed.

For example... When driving forward each track gets 50% of the total torque. However, if the tank is steering fully left and the InsideTrackTorqueCurve is 0.2, this will apply 20% of the engine torque to the left track and the remaining 80% will be applied to the right track. If the InsideTrackTorqueCurve is -0.2 it will still split the torque 20/80 however the inside torque will be applied in the reverse direction. EngineDamping is a damping force invesely proptional to the speed of each track.

Keep in mind that total torque is conserved across both tracks so if you were to direct 100% to the inside track there wouldn't be any torque left to send to the outside track. In addition, any track wheels with a positive SteerFactor will have their lateral stiffness adjusted using TurnMaxGripReduction/TurnGripScaleRate when tracks are at different speeds.

If bTurnInPlaceOnSteer is TRUE, TurnInPlaceThrottle allows you to set a reduced amount of throttle for turning in place.

Content: The Physics Asset

You set up the collision for a vehicle using PhAT, in the same way as a ragdoll. However, vehicles use the bUseSingleBodyPhysics flag in their SkeletalMeshComponent, which only creates a single physics body (from the root body) for the component, instead of one body for each part of the PhysicsAsset. The other bodies you set up in PhAT for the vehicle play no part in the physics simulation of the vehicle. There is no need to create joints for wheels etc. The other bodies in the PhysicsAsset are used for Unreal collision line checks though, so it can be useful to add extra bodies to stop player movement more accurately, especially on animating parts.

See the Setting up Vehicles page for information about creating vehicles in a 3D package and importing them into the engine.

Performance: Tuning Vehicles

Tuning a vehicle is more of an art than a science.

Useful Console Commands

A very useful tool however is the ‘editactor’ console command. To use this, run the game with the –wxwindows switch (or use PIE). Then get into the vehicle you want to tune and type ‘editactor class=’, and you should see a property window appear allowing you to edit all the vehicle properties whilst driving your vehicle. Note that properties that are only used at construction time (eg BoneOffset) cannot be changed on the fly.

Vehicle Replication

Here are some strategies for vehicle replication, as done in Unreal Tournament:

Physics is fully simulated on both the client and server. When a client presses forwards, that goes to the server as a 'raw' input. Then it gets turned into vehicle-specific Throttle, Steering etc. settings on the server, and replicated to all clients - along with the current state of the vehicle (linear and angular, position and velocity). That way inputs and vehicle state are kept in sync. The physics state of the vehicle on the client are corrected in 3 ways:

  1. If it is very small, it is ignored.
  2. If it is fairly small and vehicle is moving, some percentage of the error is corrected directly, and the velocity is modified to move the client version towards the server version.
  3. If it is large, it just teleports to the new location.

This code is in AActor::ApplyNewRBState. This data is replicated using a struct, to keep all the fields in sync. This is the VehicleState struct in SVehicle.uc.

A good way to debug and visualize this is to ignore physics corrections from the server, and draw them instead. This code is actually in the ApplyNewRBState function - look for the Handy debugging mode comment near the top. This way you can drive around and see how quickly the client and server version of the vehicle diverge.

Most effects are handled entirely on the client, by interrogating the client's physics state (velocity, contacts etc).

Strategies for Other Games

For games with very high-speed vehicles handle this situation, such as racing games, there are other strategies to consider. The larger the velocities, the more aggressive you may need to be with 'teleport' corrections. If you have a reasonable number of vehicles, you may always want the server authoritative with physics simulation. If you are making an MMO with hundreds of vehicles, you may need to distribute the simulation.