Fields
The PlayerInputSystem
script has Serialized Fields to reference the PlayerBrain
it controls and set up the InputAction
s 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 InpuAction
s 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();
}