the symptom, in your words

"Gamepad triggers have a public analog read: Input.GetAnalog works"

✓ verified on 26.07.08e
lane Writing gameplayposted updated

▸ SYMPTOM

You bind a gamepad trigger (e.g. "RightTrigger") to an Input.config action expecting to read a smooth 0–1 pull value, but only get digital on/off via Input.Down / Input.Pressed / Input.Released. It looks like there's no analog axis for triggers.

▸ CAUSE

There are two separate input surfaces, and the confusion is using the wrong one:

  1. Named Input.config actions bound to a trigger ("GasTrigger""RightTrigger") are read via Input.Down / Input.Pressed / Input.Released: digital threshold only, no pull value.
  2. Input.GetAnalog(InputAnalog) reads the physical trigger axis directly, returning a smooth 0..1 float, completely independent of any config-action binding.

The InputAnalog enum has explicit per-axis members: LeftStickX, LeftStickY, RightStickX, RightStickY, LeftTrigger, RightTrigger. There is no InputAnalog.Move member: the old assumption that InputAnalog only backs Move/Look aggregates was incorrect.

▸ FIX

Use Input.GetAnalog directly for proportional trigger reads:

snippet
float throttle = MathF.Max(
    Input.AnalogMove.y,                              // stick: smooth 0..1
    Input.GetAnalog( InputAnalog.RightTrigger ) );    // trigger: smooth 0..1

float brake = MathF.Max(
    -Input.AnalogMove.y,
    Input.GetAnalog( InputAnalog.LeftTrigger ) );

Two engine behaviors to know:

  • GetAnalog returns 0 unless Input.UsingController is true: a keyboard player reads 0, so you can safely MAX-blend keyboard and trigger without interference.
  • The engine pre-applies a 12.5 % deadzone before the value is exposed, so resting triggers can't creep regardless of your own deadzone settings.

This compiles clean through the whitelist enforcer (Sandbox.Generator access analyzer): no internal or NativeEngine access needed.

▸ WHY IT WORKS

The named-action system treats triggers as buttons (threshold press/release), but the InputAnalog API reads the raw axis value from the controller hardware. By reading the trigger through GetAnalog instead of a named action, you get the full analog range the hardware provides. The two surfaces are independent: you can keep named actions for digital fire/jump bindings while reading triggers proportionally for throttle/brake.

Verified on engine 26.07.08e: seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?
changelog
  • Corrected: Input.GetAnalog(InputAnalog.LeftTrigger/RightTrigger) is a real public 0..1 read. The article previously claimed no analog API exists.
  • Published

Want to know when new guides or fixes drop? Join the community to help build this out. Report gotchas, flag outdated fixes, or just lurk.

Join the Discord