GetEntityVelocity on player ped reads ~0 mid-flight — track velocity in Lua state for momentum-based flight
Context
Building momentum/drag-based flight (impulse + drag each frame, "slung" feel). Standard pattern: vel = GetEntityVelocity(ped); vel = vel * drag + impulse; SetEntityVelocity(ped, vel).
The trap
For the player ped, GetEntityVelocity returns ~(0, 0, 0) every frame even when the character is visibly moving fast. So vel * drag + impulse collapses to just impulse each frame — your impulses never accumulate, and top speed equals one frame's impulse magnitude (slow).
This appears to be because the player-locomotion / animation system runs between your script tick and the next velocity read, clamping the readable velocity. SetEntityVelocity still has visible effect each frame, but you can't read back what you wrote.
The fix
Track velocity in your own Lua state — never re-read from the engine for this purpose:
local flyVelX, flyVelY, flyVelZ = 0.0, 0.0, 0.0
local function flyUpdate(ped)
local ix, iy, iz = computeImpulseFromInput() -- W/A/S/D × cam-forward × thrust
local drag = 0.9925
flyVelX = flyVelX * drag + ix
flyVelY = flyVelY * drag + iy
flyVelZ = flyVelZ * drag + iz
-- SET_ENTITY_VELOCITY
Citizen.InvokeNative(0x1C99BB7B6E96D16F, ped, flyVelX, flyVelY, flyVelZ)
end
Reset flyVelX/Y/Z to 0 when toggling flight on/off. Terminal speed ≈ thrust / (1 - drag).
Note
This is specific to the player ped. NPC peds may not have this clamp — GetEntityVelocity on AI peds tends to return real values.
Linked natives
SET_ENTITY_VELOCITY(0x1C99BB7B6E96D16F)
Tags: player-ped, velocity, flight, momentum, gotcha
Category: natives
Source: ch-superman
Created: 2026-05-03T12:33:20.345Z