New Input System: Held on keyboard but toggle on gamepad (sprinting)

Hello,

Is it possible without adding any game logic to have:

  • control scheme A: actions are triggered on hold
  • control scheme B: actions are triggered on toggle

A practical example is the action of sprinting.
On the keyboard, the player needs to hold shift to sprint.
On the gamepad, the player needs to press the thumbstick, but he doesn’t need to hold it. If he presses again it will stop sprinting (toggle).

I could check what is the current control scheme to differentiate those 2 cases, but I was wondering if there is a solution by using the interactions.

I’ve tried to use 2 actions: StartSprint and StopSprint :

GameInputs.Character.StartSprint.performed += OnStartSprintTriggered;
GameInputs.Character.StopSprint.performed += OnStopSprintTriggered;

private void OnStartSprintTriggered(InputAction.CallbackContext obj)
{
    _sprint = true;
}

private void OnStopSprintTriggered(InputAction.CallbackContext obj)
{
    _sprint = false;
}

On the keyboard, StartSprint has a Press interaction with Press, and StopSprint has a Press interaction with Release. This works.
But on the gamepad, StartSprint has a Press interaction with Press, and StopSprint has a Press interaction with Press, and both are conflicting.

Thanks!

Here is actually a way to do this with the action setup I was mentioning.

  • On the keyboard, StartSprint has a Press interaction with Press, and StopSprint has a Press interaction with Release.
  • On the gamepad, StartSprint has a Press interaction with Press, and StopSprint has a Press interaction with Press.

By using pooling instead of events, there is no possible conflicts between the actions :

public void Update()
{
    if (_sprint)
    {
        if (GameInputs.Character.Sprint.triggered)
        {
            _sprint = false;
        }
    }
    else
    {
        if (GameInputs.Character.Sprint.triggered)
        {
            _sprint = true;
        }
    }
}

I suppose it would be possible to do this with events too, by subscribing and unsubscribing. But it feels really overkill.

Actually I find this to be a better solution :

I use 2 different actions:

  • SprintToggle: Binded on gamepad to Left Stick Press. Not binded on Keyboard.
  • SprintHold: Binded on keyboard to Shift. Not binded on Gamepad.

Then:

        GameInputs.Character.SprintToggle.performed += OnSprintTogglePerformed;
        GameInputs.Character.SprintHold.performed += OnSprintHoldPerformed;
        GameInputs.Character.SprintHold.canceled += OnSprintHoldCanceled;

        private void OnSprintTogglePerformed(InputAction.CallbackContext obj)
        {
            _sprint = !_sprint;
        }

        private void OnSprintHoldPerformed(InputAction.CallbackContext obj)
        {
            _sprint = true;
        }

        private void OnSprintHoldPerformed(InputAction.CallbackContext obj)
        {
            _sprint = false;
        }

This has the advantage of being able to let the player rebind each actions.

2 Likes