03. Input and Game Controller

Overview

Interaction with the keyboard or a gamepad is the most important part in making a piece of software become a game. Listening to key-state changes is done by inserting an event handler method into the static OnKey event of the Input class.

The callback method receives an event argument which contains information if a certain key or button is triggered.

Key States

The following list shows you the several states at which a key or button can be in:

  • KeyPressed: This event fires the first frame when the key is held down.
  • KeyDown: This event fires every frame when the key is held down.
  • KeyUp: This event fires when a key is released.
  • KeyChanged: This event is used for analog input devices which provides values between 0 and 1. This event is for example fired when the mouse-position has changed.
public virtual void OnAwake()
{
  // Hook on to Key input events.
  Input.OnKey += OnKey;
}

private void OnKey(InputEvent inputEvent)
{
  // Commands which are only allowed when game is currently running and not paused.
  if(State == GameState.Running)
  {
    // Fire primary player weapon.
    if((inputEvent.KeyPressed(KeyId.Space) || inputEvent.KeyPressed(KeyId.XI_A)) && Playership.Entity.Exists)
    {
      Playership.Fire();
    }
  }
}

Controlling the Player

Player control is achieved using the function UpdateSpeed of the Player class. The player's movement direction is determined by variables xVal and yVal, which are initialized based on the values of an analog game controller input.

var xVal = Input.GetInputValue(KeyId.XI_ThumbLX);
var yVal = Input.GetInputValue(KeyId.XI_ThumbLY);

Next, the values can be forced to a maximum value when using a keyboard input or a digital game controller input.

if (Input.KeyDown(KeyId.Left) || Input.KeyDown(KeyId.XI_DPadLeft))
  xVal = -1f;
if (Input.KeyDown(KeyId.Right) || Input.KeyDown(KeyId.XI_DPadRight))
  xVal = 1f;
if (Input.KeyDown(KeyId.Down) || Input.KeyDown(KeyId.XI_DPadDown))
  yVal = -1f;
if (Input.KeyDown(KeyId.Up) || Input.KeyDown(KeyId.XI_DPadUp))
  yVal = 1f;

At this point, the x and y values represent the intended movement direction. In order to give an impression of inertia the values are multiplied with an acceleration constant and eventually applied to movement values (_forwardSpeed and _upSpeed). To prevent the player from flying outside of the screen boundaries the player's speed is clamped with ClampSpeed before assigning it back to the Speed variable. If the position is outside of a given boundary, then the speed values are changed so they will always move back to edge of the boundary.

// In case new position on screen is outside of bounds
ClampSpeed(ref _forwardSpeed, ref _upSpeed);

Speed = new Vector3(0, _forwardSpeed, _upSpeed);

The movement values are stored in the Speed variable and are applied to the PhysicsEntity by setting the Velocity in the Move method of the DestroyableBase class. For further information about physics processing see the chapter Physics Interaction.