Player Input System

Fields

The PlayerInputSystem script has Serialized Fields to reference the PlayerBrain it controls and set up the InputActions it will use in the Input System package.

public class PlayerInputSystem : MonoBehaviour
{
    [SerializeField]
    private PlayerBrain _States;

    [Header("Input Actions")]

    [SerializeField]
    [Tooltip("Space by default")]
    private InputAction _JumpAction;

    [SerializeField]
    [Tooltip("Left Click by default")]
    private InputAction _PrimaryAttackAction;

    [SerializeField]
    [Tooltip("Right Click by default")]
    private InputAction _SecondaryAttackAction;

    [SerializeField]
    [Tooltip("Left Shift by default")]
    private InputAction _RunAction;

    [SerializeField]
    [Tooltip("WASD and Arrow Keys by default")]
    private InputAction _MovementAction;

Reset

When you first add a component (or use the Reset command in its Inspector context menu) Unity will run its Reset method, so we use it to set up default bindings for each of the actions. The Platformer Game Kit is currently only designed for a single Player, but this would allow it to support multiple players by simply giving them each different bindings in the Inspector.

protected virtual void Reset()
{
    Animancer.AnimancerUtilities.GetComponentInParentOrChildren(gameObject, ref _States);

    _JumpAction = new InputAction("Jump", InputActionType.Button, "<Keyboard>/space");
    _JumpAction.AddBinding("<Gamepad>/buttonSouth");

    _PrimaryAttackAction = new InputAction("Primary Attack", InputActionType.Button, "<Mouse>/leftButton");
    _PrimaryAttackAction.AddBinding("<Gamepad>/buttonEast");

    _SecondaryAttackAction = new InputAction("Secondary Attack", InputActionType.Button, "<Mouse>/rightButton");
    _SecondaryAttackAction.AddBinding("<Gamepad>/buttonNorth");

    _RunAction = new InputAction("Run", InputActionType.Value, "<Keyboard>/shift");
    _RunAction.AddBinding("<Gamepad>/buttonWest");

    _MovementAction = new InputAction("Movement", InputActionType.Value, expectedControlType: "Vector2");
    _MovementAction.AddCompositeBinding("2DVector")
        .With("Up", "<Keyboard>/w")
        .With("Down", "<Keyboard>/s")
        .With("Left", "<Keyboard>/a")
        .With("Right", "<Keyboard>/d");
    _MovementAction.AddCompositeBinding("2DVector")
        .With("Up", "<Keyboard>/upArrow")
        .With("Down", "<Keyboard>/downArrow")
        .With("Left", "<Keyboard>/leftArrow")
        .With("Right", "<Keyboard>/rightArrow");
    _MovementAction.AddCompositeBinding("2DVector(mode=2)")
        .With("Up", "<Gamepad>/leftStick/up")
        .With("Down", "<Gamepad>/leftStick/down")
        .With("Left", "<Gamepad>/leftStick/left")
        .With("Right", "<Gamepad>/leftStick/right");
}

Runtime

Unlike the Player Input Manager which checks each of its buttons every frame, the Input System package is event based so we simply register callbacks to the appropriate events in Awake and the system will invoke those callbacks when the corresponding buttons are pressed.

protected virtual void Awake()
{
    _JumpAction.started += context => _States.TryJump();
    _PrimaryAttackAction.started += context => _States.TryPrimaryAttack();
    _SecondaryAttackAction.started += context => _States.TrySecondaryAttack();
    _RunAction.performed += context => _States.Character.Run = context.action.IsPressed();
    _MovementAction.performed += context => _States.Character.MovementDirection = context.ReadValue<Vector2>();
    _MovementAction.canceled += context => _States.Character.MovementDirection = default;
}

The InpuActions also need to be enabled and disabled with this component so they know when to start and stop listening to input.

protected virtual void OnEnable()
{
    _JumpAction.Enable();
    _PrimaryAttackAction.Enable();
    _SecondaryAttackAction.Enable();
    _RunAction.Enable();
    _MovementAction.Enable();
}

protected virtual void OnDisable()
{
    _JumpAction.Disable();
    _PrimaryAttackAction.Disable();
    _SecondaryAttackAction.Disable();
    _RunAction.Disable();
    _MovementAction.Disable();
}