Input
Actions, device polling, gamepads and haptics. Touch and gestures have their own page — Touch. For setting up .jinput action maps, see the Input guide.
Actions
Input.GetAction(string mapDotAction, int player = 0)
Looks up an action by "MapName/ActionName" and returns an InputAction handle.
m_Jump = Input.GetAction("Gameplay/Jump");
m_Move = Input.GetAction("Gameplay/Move", player: 1);Cache the handle
This resolves the string through a native lookup on every call. Do it once in OnCreate and keep the result in a field — the handle stays valid, and re-resolving per frame is exactly the cost the API is shaped to avoid.
An unknown name returns an invalid handle rather than throwing. Every query on it reads neutral — false, 0, Vector2.Zero — so a typo produces an action that silently does nothing. Check IsValid when something mysteriously doesn't respond.
InputAction
| Member | What it gives you |
|---|---|
IsPressed | true the whole time it's held |
WasPressedThisFrame | true for exactly one frame, on the press |
WasReleasedThisFrame | true for exactly one frame, on the release |
ReadFloat() | The value of an Axis1D action. 0 for other types |
ReadVector2() | The value of an Axis2D action. Vector2.Zero for other types |
IsValid | Whether the name resolved to a real action |
public class Player : GameEntity
{
private InputAction m_Move, m_Jump;
protected override void OnCreate()
{
m_Move = Input.GetAction("Gameplay/Move");
m_Jump = Input.GetAction("Gameplay/Jump");
}
protected override void OnUpdate(float ts)
{
Vector2 move = m_Move.ReadVector2();
Translation += new Vector3(move.X, move.Y, 0) * m_Speed * ts;
if (m_Jump.WasPressedThisFrame)
Jump();
}
}For a Hold interaction, IsPressed only becomes true once the hold threshold is crossed; WasPressedThisFrame is the threshold-crossing frame. For a Tap, it's the release-within-window frame. What the edge means is declared by the action, not by the reading code.
Local multiplayer
Input.AssignGamepadToPlayer(int slot, int player)
Assigns a gamepad slot (0–3) to a player index. Every slot defaults to player 0, so single-player games never call this.
Input.GetGamepadPlayer(int slot)
Which player that slot is assigned to.
Keyboard and mouse
For menus, debug keys, and anything an action map would be overkill for.
| Method | Returns |
|---|---|
Input.IsKeyDown(KeyCode key) | true while held |
Input.WasKeyPressedThisFrame(KeyCode key) | true for the press frame |
Input.WasKeyReleasedThisFrame(KeyCode key) | true for the release frame |
Input.IsAnyKeyDown() | true while any key is held — "press any key" |
Input.IsMouseButtonDown(MouseCode button) | true while held |
Input.WasMouseButtonPressedThisFrame(MouseCode button) | true for the press frame |
Input.WasMouseButtonReleasedThisFrame(MouseCode button) | true for the release frame |
Input.GetMousePosition() | Pointer position in window pixels |
Input.GetMouseDelta() | Movement since last frame, in pixels |
Input.GetScrollDelta() | This frame's scroll offset. Desktop only; reads zero elsewhere |
Input.IsPointerDown() | true for the left mouse button or any touch |
if (Input.WasKeyPressedThisFrame(KeyCode.Escape))
TogglePause();
Vector3 world = m_Camera.ScreenToWorld(Input.GetMousePosition());Mouse position is in screen space — pixels, origin top-left, +Y down — the same space CameraComponent.WorldToScreen produces, so values pass between them directly. See Camera.
Input.IsPointerDown() is the one to reach for when a control should work with either a mouse or a finger without branching.
Gamepads and haptics
Gamepad controls are read through actions — bind Gamepad/South, Gamepad/LeftStick and so on in your .jinput. Button names are positional (South, East, West, North), so one binding covers Xbox, PlayStation and generic pads.
Rumble is called directly, on a gamepad slot (0–3).
Input.RumbleGamepad(int slot, float lowFreq, float highFreq, uint durationMs)
Input.RumbleGamepad(0, lowFreq: 0.6f, highFreq: 0.3f, durationMs: 150);lowFreq is the heavy motor, highFreq the light one. durationMs is required and clamped to an engine ceiling.
Input.RumbleGamepadTriggers(int slot, float left, float right, uint durationMs)
Trigger-only rumble — desktop and Xbox-class pads. A silent no-op everywhere else.
Input.StopGamepadRumble(int slot)
Silences that slot before its duration would have expired.
Input.StopAllGamepadRumble()
Every slot, every motor. Call it when opening a pause menu.
Input.PlayGamepadHaptic(int slot, string relativePath)
Plays an authored .jhaptic envelope — for anything with more shape than a single buzz. Replaces whatever curve was already playing on that slot.
Input.PlayGamepadHaptic(0, "Haptics/Explosion.jhaptic");Input.SetHapticIntensity(float intensity) / Input.GetHapticIntensity()
A global 0–1 multiplier over every rumble and haptic, including a .jhaptic's own curve. 0 means genuinely nothing vibrates. A settings screen is the intended caller.
Input.SetHapticIntensity(Settings.GetFloat("haptics.intensity", 1.0f));Rumble calls are always safe
A keyboard-only player and a pad with no motors both silently do nothing, so you never need to check first. Rumble never fires outside Play mode either.
Input and editor focus
While the editor has focus, input is suppressed for the game — otherwise typing an entity name would also move your player. A suppressed frame reads neutral (buttons up, positions and deltas zero), never a stale value frozen mid-press. This applies to everything on this page uniformly.
See also
- Touch — the touchscreen and gestures
- Input guide — action maps, bindings, on-screen controls
- Camera — converting between screen and world space
- Saving and settings — persisting rebinds and haptic intensity