#movement
11 items (1 guide · 10 fixes)
A per-run accumulator guard (budget, cooldown, or streak counter) that resets on a transient state flicker never actually fires, because the reset zeroes it faster than it can fill. Reset only on a signal that truly ends the episode (sustained air, real forward progress), never on a per-tick proxy the episode itself trips constantly.
A side-by-side follow slot must sit perpendicular to the leader's own heading, never perpendicular to the line between the two characters. The line-between-the-pair definition is circular, because it is built from where the follower already is, so each correction chases the last one and the pair collapses to single file. Measured error was 89.6 degrees from the line rule versus 0.2 degrees from the heading rule. Derive the slot axis from the leader's forward vector rotated 90 degrees.
An idempotent ground-snap jitters on curved terrain because the slope curves away within each step: ease the downward snap at a bounded glue rate.
A grounded wish-speed servo (MoveTowards) silently clamps any externally applied velocity (mantle carry, knockback, launch) to the wish target within a few ticks of ground contact -- boundary measurements read green while the effect is imperceptible.
A per-frame visual-smoothing offset computed from raw fixed-tick state double-smooths against the engine's built-in FixedUpdateInterpolation, producing a 50 Hz sawtooth that reads as model flicker on stepped terrain: delete the manual smoother or compute against interpolated state.
Always handle tr.StartedSolid: ignore that frame so an overlapped body can walk free; slide-trace the wish onto the hit plane.
A trace-swept NPC with 'wall ahead, hold position this frame' freezes permanently when the desired direction is constant -- the identical trace hits the identical wall every frame.
SceneTraceResult.EndPosition on a sphere-radius sweep is the sphere's CENTRE at contact, not the contact point. Treating it as where the feet landed is off by a full radius. Derive the real contact position as from + (to - from) * Fraction in one helper. A related trap: snapping the sphere exactly tangent to the floor makes the next horizontal sweep intermittently report StartedSolid.
Sandbox.PlayerController's WalkSpeed / RunSpeed / DuckedSpeed / Speed are private serialized [Property] fields, so an external component can't cleanly scale player move speed (e.g. for a slow/root effect). WishVelocity is public but recomputed every fixed-update, so writing it is order-dependent. Swap in or subclass a controller that exposes a public knob.
A hand-integrated trace mover has no collider component: ITriggerListener and OnTriggerEnter never fire. Use distance-polling instead.