Revision Difference
Input_System#549687
<cat>Code.Input</cat>
<title>Input System</title>
Input is part of [The Game Loop](https://wiki.facepunch.com/sbox/GameLoop), every frame our clients build their input, converting your mouse, keyboard and controller inputs into a Command that is sent to the server each tick.
⤶
## Client Input Properties⤶
⤶
You can mark properties on a [Pawn](https://wiki.facepunch.com/sbox/Pawn) or [Entity Component](https://wiki.facepunch.com/sbox/Entity_Components) attached to a [Pawn](https://wiki.facepunch.com/sbox/Pawn) with the `[ClientInput]` attribute. Properties with this attribute are automatically serialized and sent to the server in a Command each tick. Before [Simulate](https://wiki.facepunch.com/sbox/GameLoop#simulate) is called on the client and server these properties are reset to the correct values from the Command.⤶
⤶
### Supported Types⤶
⤶
- float⤶
- int⤶
- bool⤶
- string⤶
- Vector2⤶
- Vector3⤶
- Rotation⤶
- Angles⤶
- Transform⤶
- Entity⤶
- ButtonState⤶
⤶
## Help, I'm Upgrading⤶
⤶
If you are currently transitioning from the old way of doing things to the new way, here are some pointers:⤶
⤶
`Input.Rotation` is gone. In most cases this isn't really needed for games that aren't an FPS. You can implement your own version of this (see [Building Input](Input_System#buildinginput) for a view angles implementation example).⤶
⤶
`Input.Forward` and `Input.Left` are gone. These values are basically just `Input.AnalogMove.x` and `Input.AnalogMove.y` respectively, so there's no need to have them.⤶
⤶
### Examples⤶
⤶
You can checkout the [Sandbox](https://github.com/facepunch/sandbox) gamemode to see how it has been upgraded to this system. Examples include ActiveChild, InputDirection and ViewAngles.⤶
⤶
## Building Input⤶
⤶
Every frame `BuildInput()` gets called clientside. The static `Input` class can be used to grab raw input data and then use that data to set any properties with the `[ClientInput]` attribute.⤶
Input is part of [The Game Loop](https://wiki.facepunch.com/sbox/GameLoop).
⤶
Every frame our clients build their input, converting your mouse, keyboard and controller inputs into a Command that is sent to the server each tick.⤶
⤶
# Actions⤶
⤶
To convert inputs from your keyboard, mouse and controller into the game we have a system called Actions.⤶
⤶
You can edit your actions in your Project Settings.⤶
⤶
<upload src="1/8db41a83ec8a45f.png" size="98728" name="image.png" />⤶
⤶
## Using Actions⤶
⤶
The Input class has a number of methods to help you use Actions.⤶
```csharp
// An example BuildInput method within a player's Pawn class.⤶
[ClientInput] public Vector3 InputDirection { get; protected set; }⤶
[ClientInput] public Angles ViewAngles { get; set; }⤶
⤶
public override void BuildInput()
⤶
//⤶
// view button was just pressed this tick⤶
//⤶
if ( Input.Pressed( "view" ) )
{
InputDirection = Input.AnalogMove;⤶
⤶
var look = Input.AnalogLook;⤶
⤶
var viewAngles = ViewAngles;⤶
viewAngles += look;⤶
ViewAngles = viewAngles.Normal;⤶
// open a menu⤶
}
```⤶
⤶
## Simulate⤶
⤶
Every tick clients send a **Command** that contains the values constructed from BuildInput. This command then gets simulated in `Game.Simulate( Client )` for each client.⤶
⤶
Within Simulate( Client ) the static [Input](https://asset.party/api/Sandbox.Input) class contains inputs specific to the currently simulated client, this allows you to run the same code on both the server and client for [Prediction](Prediction).
⤶
```csharp⤶
// An example Simulate method within a player's Pawn class.⤶
⤶
public override void Simulate( Client cl )⤶
⤶
//⤶
// attack1 button is down⤶
//⤶
if ( Input.Down( "attack1" ) )
{
if ( Input.Pressed( InputButton.Jump ) )⤶
{⤶
Velocity += Vector3.Up * 100f;⤶
}⤶
⤶
Velocity += InputDirection * 400f;⤶
Rotation = ViewAngles.ToRotation();⤶
// open a menu⤶
}
```⤶
⤶
### Button State⤶
⤶
A `[ClientInput]` property can also be a `ButtonState`. This struct lets you treat an input as if it were a button, so that in Simulate you can get whether it was "pressed" or "released" or whether it is "down". This can make stuff like couch co-op easier.⤶
⤶
```csharp⤶
[ClientInput] public ButtonState Jump { get; set; }⤶
⤶
public override void BuildInputs()⤶
⤶
//⤶
// the jump button was just released this tick⤶
//⤶
if ( Input.Released( "jump" ) )⤶
{
if ( IsPlayerOne )⤶
Jump = Input.Down( InputButton.Jump );⤶
else if ( IsPlayerTwo )⤶
Jump = Input.Down( InputButton.Drop );⤶
// open a menu⤶
}
⤶
public override void Simulate( Client client )⤶
{⤶
if ( Jump.Pressed )⤶
{⤶
Velocity += Vector3.Up * 100f;⤶
}⤶
}⤶
⤶
⤶
```
⤶
## Keys with InputButton⤶
⤶
s&box does not provide raw access to the user's keyboard, instead there is a set of standard bindings your game can make use of.⤶
⤶
### Default Bindings⤶
⤶
| InputButton | Binding | Default | Controller Default |⤶
| ------------------------ | ---------------- |:-------:|:------------------:|⤶
| `InputButton.Forward` | `+iv_forward` | W | Unbound ( Analog ) |⤶
| `InputButton.Back` | `+iv_back` | S | Unbound ( Analog ) |⤶
| `InputButton.Left` | `+iv_left` | A | Unbound ( Analog ) |⤶
| `InputButton.Right` | `+iv_right` | D | Unbound ( Analog ) |⤶
| `InputButton.Jump` | `+iv_jump` | Space | A |⤶
| `InputButton.Duck` | `+iv_duck` | Ctrl | B |⤶
| `InputButton.Run` | `+iv_sprint` | Shift | Left Stick Press |⤶
| `InputButton.Walk` | `+iv_walk` | Alt | Unbound |⤶
| `InputButton.PrimaryAttack` | `+iv_attack` | Mouse1 | RT ( Soft press ) |⤶
| `InputButton.SecondaryAttack` | `+iv_attack2` | Mouse2 | LT ( Soft press ) |⤶
| `InputButton.Reload` | `+iv_reload` | R | X |⤶
| `InputButton.Grenade` | `+iv_grenade` | | |⤶
| `InputButton.Drop` | `+iv_drop` | G | |⤶
| `InputButton.Use` | `+iv_use` | E | Y |⤶
| `InputButton.Flashlight` | `+iv_flashlight` | F | DPAD UP |⤶
| `InputButton.View` | `+iv_view` | C | Right Stick Press |⤶
| `InputButton.Zoom` | `+iv_zoom` | Mouse3 | Unbound |⤶
| `InputButton.Menu` | `+iv_menu` | Q | Pause Button |⤶
| `InputButton.Score` | `+iv_score` | Tab | Back Button |⤶
| `InputButton.Chat` | `?` | | |⤶
| `InputButton.Voice` | `+iv_voice` | V | |⤶
| `InputButton.SlotNext` | `+iv_slotnext` | | RB |⤶
| `InputButton.SlotPrev` | `+iv_slotprev` | | LB |⤶
| `InputButton.Slot1` | `+iv_slot1` | 1 | DPAD LEFT |⤶
| `InputButton.Slot2` | `+iv_slot2` | 2 | DPAD RIGHT |⤶
| `InputButton.Slot3` | `+iv_slot3` | 3 | DPAD DOWN |⤶
| `InputButton.Slot4` | `+iv_slot4` | 4 | |⤶
| `InputButton.Slot5` | `+iv_slot5` | 5 | |⤶
| `InputButton.Slot6` | `+iv_slot6` | 6 | |⤶
| `InputButton.Slot7` | `+iv_slot7` | 7 | |⤶
| `InputButton.Slot8` | `+iv_slot8` | 8 | |⤶
| `InputButton.Slot9` | `+iv_slot9` | 9 | |⤶
| `InputButton.Slot0` | `+iv_slot0` | 0 | |⤶
⤶
<note>You should rely on what the action actually does rather then binding to any specific keys.</note>⤶
⤶
### Getting Bound Keys⤶
⤶
You can get the key the user has bound to a button with `Input.GetButtonOrigin( InputButton )`, this can be used to prompt the user what key or controller button to press.⤶
⤶
```csharp⤶
string useButton = Input.GetButtonOrigin( InputButton.Use );⤶
```⤶
⤶
⤶
⤶
## When To Use Actions⤶
⤶
On the client you can use the `Input` methods anywhere. ⤶
⤶
On the server you should only call Input during a `Simulate` call on a pawn. In this instance the `Input` will return the correct values for the owner of that pawn.⤶
⤶
⤶
# AnalogMove⤶
⤶
`Input.AnalogMove` is generated automatically from controller input and any actions you have named "forward", "backward", "left" and "right". ⤶
⤶
This is a `Vector3` representing the move input.⤶
⤶
You can safely use this for something like player movement input but you should sanity check it first. For example, you might want to normalize it.⤶
⤶
# AnalogLook⤶
⤶
`Input.AnalogLook` is generated automatically from controller and mouse input.⤶
⤶
This represents the view angles. This could be used in something like a first person shooter to represent the eye angles or rotation of an entity.⤶