The Input static class provides everything you need to read player input. Actions are defined as named strings (e.g. "Attack1", "Jump") so your code never references raw keycodes — the player can rebind anything.
Querying actions
Use these three methods to check the state of an action each frame. Call them inside OnUpdate or OnFixedUpdate.
// True every frame while the button is held
if ( Input.Down( "Attack1" ) ) { }
// True only on the frame the button was first pressed
if ( Input.Pressed( "Jump" ) ) { }
// True only on the frame the button was released
if ( Input.Released( "Duck" ) ) { }
Input queries return false automatically when input is suppressed (e.g. while a UI element has focus), so you don’t need to guard against it yourself.
AnalogMove
Input.AnalogMove is a Vector3 built from the four directional actions (Forward, Backward, Left, Right). Use it as a movement direction in local space.
protected override void OnFixedUpdate()
{
var wishDir = Input.AnalogMove; // normalized direction in local space
var velocity = wishDir * MoveSpeed;
characterController.Move( velocity * Time.Delta );
}
AnalogLook
Input.AnalogLook is an Angles value derived from mouse delta (and gamepad right stick). It is already scaled by the player’s sensitivity preference.
protected override void OnUpdate()
{
EyeAngles += Input.AnalogLook;
EyeAngles = EyeAngles.WithPitch( EyeAngles.pitch.Clamp( -89f, 89f ) );
}
MouseDelta
Raw mouse movement in screen pixels since the last frame:
Vector2 delta = Input.MouseDelta;
MouseWheel
Scroll wheel input as a Vector2 (y is the usual vertical scroll):
float scroll = Input.MouseWheel.y;
MouseCursorVisible
Check whether the cursor is currently visible (e.g. a menu is open):
if ( Input.MouseCursorVisible )
{
// Don't rotate the camera while cursor is shown
return;
}
You can force an action on or off from code:
// Simulate a button press
Input.SetAction( "Jump", true );
// Release it
Input.Clear( "Jump" );
// Release all actions
Input.ReleaseActions();
Default actions
When no custom input settings are defined, s&box provides these built-in actions:
Movement
Actions
Inventory
Misc
| Action | Default key | Gamepad |
|---|
Forward | W | — |
Backward | S | — |
Left | A | — |
Right | D | — |
Jump | Space | A button |
Run | Shift | Left stick click |
Walk | Alt | — |
Duck | Ctrl | B button |
| Action | Default key | Gamepad |
|---|
Attack1 | Mouse 1 | Right trigger |
Attack2 | Mouse 2 | Left trigger |
Reload | R | X button |
Use | E | Y button |
Drop | G | — |
Flashlight | F | D-pad up |
| Action | Default key | Gamepad |
|---|
Slot1–Slot9 | 1–9 | D-pad left/right/down |
SlotPrev | Mouse 4 | Left bumper |
SlotNext | Mouse 5 | Right bumper |
| Action | Default key | Gamepad |
|---|
View | C | Right stick click |
Voice | V | — |
Score | Tab | Left menu |
Menu | Q | Right menu |
Chat | Enter | — |
Define your game’s actions in Edit → Project Settings → Input. Each InputAction has:
| Field | Description |
|---|
Name | Identifier used in code, e.g. "Attack1" |
KeyboardCode | Default keyboard key/combo, e.g. "mouse1" |
GamepadCode | Mapped gamepad button |
GroupName | Category shown in the rebinding UI |
Title | Human-readable label, e.g. "Primary Attack" |
You can also create actions in C#:
// This is how the engine defines its default actions
var actions = new List<InputAction>
{
new InputAction( "Attack1", "mouse1", GamepadCode.RightTrigger )
{
GroupName = "Actions",
Title = "Primary Attack"
},
new InputAction( "Reload", "r", GamepadCode.X )
{
GroupName = "Actions"
},
};
Querying bound keys
Get the current key name for an action — useful for button prompts in your HUD:
string key = Input.GetButtonOrigin( "Jump" );
// Returns "Space" on keyboard, "A Button" on gamepad
Input contexts
Input contexts let different systems consume input independently. Each context has its own ActionsCurrent, ActionsPrevious, and mouse delta accumulators. This allows a menu system to intercept input without affecting gameplay input.
When you push a UI panel that should capture the cursor, set Mouse.Visible = true. The engine automatically zeroes out AnalogLook when the cursor is visible.
Full movement example
public sealed class PlayerController : Component
{
[Property] public float MoveSpeed { get; set; } = 200f;
[Property] public float JumpStrength { get; set; } = 350f;
Angles eyeAngles;
protected override void OnUpdate()
{
// Camera look
eyeAngles += Input.AnalogLook;
eyeAngles = eyeAngles.WithPitch( eyeAngles.pitch.Clamp( -89f, 89f ) );
Scene.Camera.WorldRotation = eyeAngles.ToRotation();
}
protected override void OnFixedUpdate()
{
var wishDir = Input.AnalogMove.Normal;
var rotation = Rotation.FromYaw( eyeAngles.yaw );
var velocity = rotation * wishDir * MoveSpeed;
if ( Input.Pressed( "Jump" ) )
{
velocity += Vector3.Up * JumpStrength;
}
WorldPosition += velocity * Time.Delta;
}
}