[New Input System] Issue with Key Hold and Release in New Input System with HoldInteraction

I’ve been working on player movement using the new input system, and I’m encountering a problem that I can’t seem to resolve. After implementing the HoldInteraction in my Input Action Asset, I noticed some unusual behavior.

When I hold the D key (to move right in a WASD pattern) and then press and hold another key like S, releasing the D key doesn’t change the direction. It’s as if the S key isn’t recognized at all. The second key is only registered (i.e., it enters the .performed state) if it’s pressed while no other key is being held down. This issue isn’t limited to just D and S; it affects all keys. For example, if I press W to move up and then press A to move left, the character continues moving up even if I release the W key while still holding A.

This problem occurs only when the HoldInteraction is set (I’ve configured it with a 0.2-second press time).

Does anyone have any ideas on why this might be happening and how to fix it? It’s driving me nuts.

Code:

using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

public class PlayerMovementController : MonoBehaviour
{
    [Header("Movement Settings")]
    [SerializeField][Range(0.1f, 10)] private float _movementSpeed = 5.0f;
    //[SerializeField][Range(0.1f, 10)] private float _movementBoost = 2.5f;

    private Rigidbody2D _rigidbody2D;
    private PlayerControls _controls;
    private Vector2 _movementInput;

    public event Action<InputAction.CallbackContext> OnMovementPerformed;

    private void Awake()
    {
        _controls = new PlayerControls();
    }

    private void Start()
    {
        _rigidbody2D = GetComponent<Rigidbody2D>();
    }

    private void OnEnable()
    {
        _controls.Gameplay.Enable();
        _controls.Gameplay.Movement.performed += HandleMovement;
        _controls.Gameplay.Movement.canceled += HandleMovement;
    }

    private void OnDisable()
    {
        _controls.Gameplay.Disable();
        _controls.Gameplay.Movement.performed -= HandleMovement;
        _controls.Gameplay.Movement.canceled -= HandleMovement;
        UnsubscribeAll();
    }

    private void FixedUpdate()
    {
        ApplyMovement();
    }

    private void HandleMovement(InputAction.CallbackContext ctx)
    {
        Vector2 input = ctx.ReadValue<Vector2>();

        // Prevent diagonal movement
        if (Mathf.Abs(input.x) > Mathf.Abs(input.y))
        {
            // Horizontal movement
            _movementInput = new Vector2(input.x, 0);
        }
        else
        {
            // Vertical movement
            _movementInput = new Vector2(0, input.y);
        }

        OnMovementPerformed?.Invoke(ctx);
    }

    private void ApplyMovement()
    {
        Vector2 movement = _movementInput * _movementSpeed;
        _rigidbody2D.velocity = movement;
    }

    private void UnsubscribeAll()
    {
        if (OnMovementPerformed != null)
        {
            foreach (var subscriber in OnMovementPerformed.GetInvocationList())
            {
                OnMovementPerformed -= (Action<InputAction.CallbackContext>)subscriber;
            }
        }
    }
}

HoldInteraction Settings:

Thank you!

This sounds like a hardware issue honestly. Here’s how to find out:

Keyboard rollover, jammed keys, bad key combinations:

https://discussions.unity.com/t/808575/2

Do not use interaction for movement. It wasn’t made for that. The ignoring stuff is deliberate AFAIK, although under-documented. What exactly do you want to achieve with the Hold?

1 Like