Home > Net >  Read "zero input" in Unity's Input System
Read "zero input" in Unity's Input System

Time:01-15

I am creating a very simple player horizontal movement script for a 2D game (code below). I want to use the newer Input System, instead of the default Input Manager.

Following Unity's guide, I was able to set the controls to work as in the example. However, the tutorial is updating the player-controlled object's position, while I want to update it's velocity. Zeroing the value read in the input, as in the example (step 4.25) works for updating positions, but not velocities, as the velocity is raised and immediately goes back to zero. But, if the velocity is not zeroed, the object's velocity is kept even after the player releases the movement key (I haven't tested it with an analog input).

Basically, when the composite input has no keys pressed (or the joystick is in the neutral position), it does not report it as a Vector2.zero. The input event only happens when a key is pressed, it seems, but not when released... at least that is what I could gather.

So I'd like to know a way to set a velocity goal, based on the Input System, that will zero out when the keys are released. Something similar to OnButtonUp() from the Input Manager.

My code:

 using UnityEngine;
 using UnityEngine.InputSystem;

 public class PlayerHorizontalMovement : MonoBehaviour
 {
     [Tooltip("[units/s]")]
     [SerializeField] private float horizontalSpeed = 3f;

     [Tooltip("[units/s^2]")]
     [SerializeField] private float horizontalAccel = 60f;

     private PlayerControls controls;

     private Rigidbody2D myRigidbody;

     private float velocityGoal;

     private void Awake()
     {
         controls = new PlayerControls();
         controls.Player.Move.performed  = context => velocityGoal = context.ReadValue<Vector2>().x;
     }

     private void Start()
     {
         myRigidbody = GetComponent<Rigidbody2D>();
         velocityGoal = 0f;
     }

     private void FixedUpdate()
     {
         Vector3 newVelocity = myRigidbody.velocity;

         // X axis velocity update
         newVelocity.x = Mathf.MoveTowards(newVelocity.x, velocityGoal, horizontalAccel * Time.fixedDeltaTime);
         myRigidbody.velocity = newVelocity;
     }

     private void OnEnable() => controls.Player.Enable();

     private void OnDisable() => controls.Player.Disable();
 }

CodePudding user response:

This should work for the old/default input system but I have no idea about the new one:

if (!Input.anyKey)
{
    Debug.Log("No button is being pressed");
}

CodePudding user response:

You’ve got a couple of options, but based on what you’ve got and the tutorial you were following, I feel the simplest would be just adding that cancelled action status, like so:

private void Awake()
{
    controls = new PlayerControls();
    controls.Player.Move.performed  = context => velocityGoal = context.ReadValue<Vector2>().x;
    controls.Player.Move.canceled  = context => velocityGoal = 0;
}

As per the Unity docs describing Actions, these are the phases you might be interested in: |Phase|Description| |-------|-------| |Disabled|The Action is disabled and can't receive input.| |Waiting|The Action is enabled and is actively waiting for input.| |Started|The Input System has received input that started an Interaction with the Action.| |Performed|An Interaction with the Action has been completed.| |Canceled|An Interaction with the Action has been canceled.|

  • Related