Character Not Moving when move left and right keys pressed simultaneously

Hi,

Im working on my character’s movement using the new input system. I running into this “problem” where if a player holds ‘a’ and ‘d’, at the same time, my character no longer moves. I know this is intended behavior with my code but I rather have it such that the character will move in the direction of the most recent key pressed. Is it possible to have this behavior?

Currently what is happening is that moveInput gets evaluated to 0 when ‘a’ (-1) and ‘d’ (1) is being pressed at the same time.

Here’s my code:

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

public class PlayerMovement : MonoBehaviour
{
    public Vector2 moveInput { get; private set; }

    [SerializeField] float _walkSpeed;
    [SerializeField] float _sprintSpeed;

    private Rigidbody _playerRb;
    private bool _sprintPressed;

    void Awake()
    {
        _playerRb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        HandleMovement();
    }

    private void HandleMovement()
    {
        float xTargetSpeed;
        float zTargetSpeed;

        xTargetSpeed = moveInput.x * _walkSpeed;
        zTargetSpeed = moveInput.y * _walkSpeed;

        _playerRb.linearVelocity = new Vector3(xTargetSpeed, _playerRb.linearVelocity.y, zTargetSpeed);
    }

    public void OnMove(InputValue input)
    {
        moveInput = input.Get<Vector2>();
    }
    
    public void OnSprint(InputValue input)
    {
        _sprintPressed = input.isPressed ? true : false;
    }
}

You haven’t written the complete code, so I can’t tell you exactly what to do. However, one possible solution is to check whether either of the two keys is pressed and then create a new vector with the desired value instead of using the existing moveInput vector directly.

Other solutions may also work, depending on how you’ve set up and are using the input system in your code.

Also, the entire if statement is duplicated code. You can simplify it by setting:
_movementSpeed = _sprintPressed ? _sprintSpeed : _walkSpeed;

Then, apply the same logic once, multiplying by _movementSpeed.

well what exact behaviour do you expect if they press left and right together?

This is not something the design of the Input System allows easily.

What you’d ideally want, is to write a composite binding – like the AxisComposite that has a AxisComposite.WhichSideWins option. However, bindings cannot have state, so it’s impossible to track the most recent active control.

On the other hand, interactions and processors can have state but they have other limitations that make them unsuitable (interactions only control the state of the action while processors cannot change the value type).

The easiest might be to implement this on top of the input system, i.e. have an action for each individual key and then combine those actions in your code. This allows you to track the last active input and fully control how the inputs are combined.

You could try to combine a composite and processor but you’d have to figure out how to pass the necessary information from the composite to the processor.

I want the character to move in the direction of the more recent pressed key. For example, if ‘a’ was being held (the character moves left) and then ‘d’ is held without ‘a’ being released, the character will move right. Instead of coming to a complete stop which is what currently happens.

Hi!

I am trying to find a solution to this issue for you with the input system team and I will let you know if I have any updates as soon as I can!

Thanks!
Zu - Unity Learn

the Input system has compsoit bindings that can conditionally be pressed “in order” so if you set up 2 bindings for d>a and a>d the movement can ignore the first key pressed and proceed in the direction of the most recent keypress

This feels like the correct way to go about this in your case.

Please let me know if you have tried this solution and if it helped you achieve this!

Zu - Unity Learn

Thanks, for the suggestion. Could you expand more on how I can do this? I’ve added a screenshot of my project settings input actions window so you can have an idea of what I’m doing!

in my game i’ve set up controller bindings (but keyboard bindings work the same way)

like this

you assign a modifier that needs to be pressed first, followed by the actual action you want to take, so the latest action is the one that gets triggered, in your case setting the modifier to d or a followed by the opposite button as the direction you want to move, should do the trick