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.
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.
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
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!
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