PhysX Vehicle scripting and control
Address every public vehicle bus with the chassis entity id. Control and state buses are reflected to BehaviorContext (Lua / Script Canvas category PhysX Vehicle). Notification events are C++-only in the shipped Gem.
Who writes input
PhysX Vehicle Drive ──┐
Lua / Script Canvas ──┼──► VehicleControlRequestBus ──► Chassis solver
C++ / AI ──┘
Use one owner for throttle / steer / brake each frame. If Drive and a script both write the control bus, the last writer wins.
VehicleControlRequestBus
| Method | Range / notes |
|---|---|
SetThrottle | [0, 1] |
SetBrake | [0, 1] |
SetSteer | [-1, 1] (left negative, right positive) |
SetHandbrake | bool |
SetGear | reverse < 0, neutral 0, forward > 0 |
SetTrackThrottle(left, right) | Tracked; typically [-1, 1] scaled to max track speed; no-op on wheeled |
C++:
#include <PhysXVehicle/VehicleControlBus.h>
PhysXVehicle::VehicleControlRequestBus::Event(
chassisEntityId, &PhysXVehicle::VehicleControlRequests::SetGear, 1);
PhysXVehicle::VehicleControlRequestBus::Event(
chassisEntityId, &PhysXVehicle::VehicleControlRequests::SetThrottle, 1.0f);
PhysXVehicle::VehicleControlRequestBus::Event(
chassisEntityId, &PhysXVehicle::VehicleControlRequests::SetSteer, -0.25f);
Lua (BehaviorContext):
VehicleControlRequestBus.Event.SetGear(self.entityId, 1)
VehicleControlRequestBus.Event.SetThrottle(self.entityId, 1.0)
VehicleControlRequestBus.Event.SetBrake(self.entityId, 0.0)
VehicleControlRequestBus.Event.SetSteer(self.entityId, 0.0)
VehicleControlRequestBus.Event.SetHandbrake(self.entityId, false)
Tracked differential:
PhysXVehicle::VehicleControlRequestBus::Event(
chassisEntityId, &PhysXVehicle::VehicleControlRequests::SetTrackThrottle,
leftThrottle, rightThrottle);
VehicleStateRequestBus
| Method | Returns |
|---|---|
GetSpeed | Forward speed along vehicle forward, m/s |
GetEngineRpm | Engine RPM from driven wheels |
GetCurrentGear | Current gear (same sign convention as SetGear) |
IsWheelGrounded(wheelIndex) | Contact this step |
GetWheelSuspensionCompression(wheelIndex) | Compression, m |
GetWheelAngularVelocity(wheelIndex) | Spin, rad/s |
GetWheelCount | Configured wheel count |
GetTrackSurfaceSpeedLeft / Right | Tracked commanded surface speed, m/s (else 0) |
GetTrackTravelDistanceLeft / Right | Accumulated travel, m, for UV scroll (else 0) |
#include <PhysXVehicle/VehicleStateBus.h>
float speed = 0.0f;
PhysXVehicle::VehicleStateRequestBus::EventResult(
speed, chassisEntityId, &PhysXVehicle::VehicleStateRequests::GetSpeed);
local speed = VehicleStateRequestBus.Event.GetSpeed(self.entityId)
local rpm = VehicleStateRequestBus.Event.GetEngineRpm(self.entityId)
local gear = VehicleStateRequestBus.Event.GetCurrentGear(self.entityId)
VehicleNotificationBus (C++ only)
| Event | Meaning |
|---|---|
OnWheelGroundedChanged(wheelIndex, grounded) | Wheel contact transition |
OnGearChanged(newGear) | Active gear changed |
OnVehicleAirborne(airborne) | All wheels left / regained ground |
These handlers are not reflected to BehaviorContext. Subscribe from C++ with VehicleNotificationBus::Handler on the chassis entity. For scripted reactions, poll state on tick or bridge through your own gameplay component.
Sample Lua driver
Gems/PhysXVehicle/Assets/Scripts/VehicleDriveExample.lua:
- Attach a Lua Script component to the chassis entity.
- Maps StartingPointInput (or Input Bindings) events:
vehicle_throttleanalog[0, 1]vehicle_brakeanalog[0, 1]vehicle_steeranalog[-1, 1]vehicle_handbrakedigital- Calls
SetGear(1)on activate and optionally logs speed / RPM / gear each second.
Disable PhysX Vehicle Drive when using this script so inputs do not fight.
Script Canvas
Look for EBus nodes under category PhysX Vehicle:
- Request nodes for each
Set*/Get*on Control and State. - Wire entity id pins to the chassis entity.
There are no Script Canvas event nodes for VehicleNotificationBus in the shipped Gem.
AI and gameplay
Typical pattern:
- Omit Drive (or set Enabled = false).
- Each AI tick (or decision), write throttle / steer / brake / gear (or
SetTrackThrottle). - Read
GetSpeed/ grounded flags for decisions. - Optionally sync track UV from travel distances in a visual component.
Configuration structs are not exposed as a live script API—author them in the editor / Prefab.
Next steps
- Debugging — confirm forces when script input seems ignored.
- Reference — include paths and cheat sheet.
- Tracked vehicles — differential control details.