How do I check if a holded button input has been released?

Hi, I’m doing a little asteroids game, and I’m trying to set a sprint function to my ship. That seems pretty easy using the input manager and setting a button hold, however, I don´t know how to check if the button was released in order to restore the ship’s speed.
I would appreciate a lot your help :slight_smile:

using UnityEngine;
using UnityEngine.InputSystem;

//asociates the script with the player object
// Ensures that the GameObject this script is attached to has a Rigidbody component
[RequireComponent(typeof(Rigidbody))]
public class NewMonoBehaviourScript : MonoBehaviour
{
    //Ship Movement parameters
    [Header("Ship Movement parameters")] [Tooltip("The velocity of the ship")]
    private Rigidbody playerRigidbody;

    private Vector3 shipMovementDirection = Vector3.zero;
    [SerializeField] private float shipSpeed = 3f * 100;
    [SerializeField] private float shipRotationSpeed = 200f;
    private float originalShipSpeed;

    private Quaternion shipRotation;

    //Fire parameters
    [Header("Fire parameters")] [SerializeField]
    private GameObject bulletPrefab;

    [SerializeField] private Transform bulletSpawnPoint;

    //Sprint parameters
    [Header("Sprint parameters")] [SerializeField]
    private float sprintEnergy = 100f;

    //Camera parameters
    [Header("Camera parameters")] [Tooltip("The camera settings")]
    private Camera mainCamera;

    void Start()
    {
        //gets the rigidbody component from the player object
        playerRigidbody = GetComponent<Rigidbody>();
        //disables gravity and rotation on the rigidbody
        playerRigidbody.useGravity = false;
        playerRigidbody.constraints = RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezeRotationX |
                                      RigidbodyConstraints.FreezePositionY;

        //gets the main camera
        mainCamera = Camera.main;
        //GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>(); //this is a slower way to get the main camera
        originalShipSpeed = shipSpeed;
    }

    //Physhics
    private void FixedUpdate()
    {
        //moves the ship in the direction of the input at a constant speed
        playerRigidbody.linearVelocity = shipMovementDirection * (shipSpeed * Time.fixedDeltaTime);
        //rotates the ship to face the mouse
        //TODO: try using lerp to make the rotation smoother
        playerRigidbody.rotation = Quaternion.RotateTowards(playerRigidbody.rotation, shipRotation,
            shipRotationSpeed * Time.fixedDeltaTime);
    }

    public void OnMove(InputValue inputValue)
    {
        //recieves an input in 2 dimensions
        Vector2 vectorInput = inputValue.Get<Vector2>();
        //as the ship moves in 3 dimensions, we only want to move in the x and z axis (y is up and down)
        shipMovementDirection = new Vector3(vectorInput.x, 0f, vectorInput.y);
        //normalizes the vector to ensure that the ship moves at the same speed in all directions
        shipMovementDirection = shipMovementDirection.normalized;
    }

    public void OnFire(InputValue inputValue)
    {
        SpawnPool.Instance.Spawn(bulletPrefab.transform, bulletSpawnPoint.position, bulletSpawnPoint.rotation);
        //creates a bullet at the bullet spawn point with the same rotation as the ship
        //Instantiate(bulletPrefab, bulletSpawnPoint.position, bulletSpawnPoint.rotation);
    }

    public void OnLook(InputValue inputValue)
    {
        Vector2 mousePosition = inputValue.Get<Vector2>();
        //converts the mouse position to a world position based on the camera position and the distance from the camera to the ship
        float zCoord = mainCamera.transform.position.y - playerRigidbody.position.y;
        Vector3 worldMousePosition =
            mainCamera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, zCoord));
        //gets the direction the ship should face
        Vector3 shipForward = worldMousePosition - transform.position;
        //sets the y value to 0 to ensure the ship doesn't rotate up or down
        shipForward.y = 0f;
        //sets the rotation of the ship to face the mouse   
        shipRotation = Quaternion.LookRotation(shipForward);
    }

    public void OnSprint(InputValue inputValue)
    {
        if (inputValue.isPressed)
        {
            shipSpeed += shipSpeed * 0.3f;
        }
        else RestoreShipSpeed();
    }
    private void RestoreShipSpeed()
    {
        shipSpeed = originalShipSpeed;
    }
}

Personally, I would reference the input’s respective InputActionReference asset via the inspector and poll its .action.IsPressed() method in Update to determine whether the ship is sprinting (or boosting?) or not.

(Also don’t call your scripts “NewMonoBehaviourScript”. Rename that into something more meaningful.)

Hi @spiney199 , that class is PlayerController.cs, I didn’t notice it was named like that, probably some refactoring went wrong, thanks for the nitpick :slight_smile:

About the InputActionReference, correct me if I’m worng, but that would mean doing it outside the script, right? I’d rather doing it inside, or in another c# class if it were necessary

No you can do it inside the script. Reference the asset in a serialised field, poll the input in Update.

Found the solution in this 4-year old post, the solution was to use press and release instead of hold :smiley:

also, pretty thanks @spiney199