Paddle movement with linear velocity doesn't stop moving when I stop holding down the key

I can code script in lua and luau but wanted to learn unity… I am following the suggested way of learning from GMTK which was really helpful (I am currently trying to make a breakout game). I started by making the movement script using Translate and restraining movement outside of the border by only changing the x position if it is in a certain range. I am now redoing the paddle movement with LinearVelocity since I think it is better and it does not ignore colliders unlike Translate. But when I tried it, the paddle never stopped moving even when I let go.

using Unity.VisualScripting;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D rigidBody;

    public float paddleSpeed;

    void FixedUpdate()
    {
        if (Input.GetKeyDown(KeyCode.D))
        {
            rigidBody.linearVelocity = Vector2.right * paddleSpeed;
        }

        if (Input.GetKeyDown(KeyCode.A))
        {
            rigidBody.linearVelocity = Vector2.left * paddleSpeed;
        }
    }
}

Either crank up the Rigidbody’s Linear Damping, which slows down linear velocity over time, or set the linear velocity to zero if neither key is pressed. The first method would slow it gradually, whereas the second would stop it instantly.

Edit: I also meant to mention that you should always poll for input inside of Update, not FixedUpdate. FixedUpdate doesn’t execute every frame, which makes it highly possible for key presses to go ‘unnoticed.’

Here’s one way you can refactor your code to properly handle input:

float horizontalInput;

void Update()
{
    horizontalInput = Input.GetAxisRaw("Horizontal");
}

void FixedUpdate()
{
    rb.velocity = Vector2.right * horizontalInput * paddleSpeed;
}

The above example actually kills two birds with one stone. Since the input is being handled inside of Update, key presses will always be registered, and since Input.GetAxisRaw returns 0 when no input is provided, the paddle will stop moving when neither A nor D is pressed (thus negating the need for some sort of separate condition).

You could also modify the logic a bit to leverage Linear Damping if you’d rather have a more gradual deceleration than an instant one.

We only miss key presses in FixedUpdate if using Input.GetKeyDown or Input.GetKeyUp. GetAxis doesn’t have this problem.

So you can do this:

    void FixedUpdate()
    {
        rb.velocity = Vector2.right * Input.GetAxisRaw("Horizontal") * paddleSpeed;
    }

Or if damping is needed then you can do this:

    void FixedUpdate()
    {
        rb.velocity = Vector2.right * Input.GetAxis("Horizontal") * paddleSpeed;
    }
1 Like

Nice, I always seem to forget about that one!

Ty. I was aware of GetAxis() but still don’t fully understand it and if it is part of the new unity input system or the old.

Updated results:

using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D rigidBody;

    public float paddleSpeed;
    public float paddleRotationSpeed;

    void Update()
    {
        if (Input.GetKey(KeyCode.D))
        {
            rigidBody.linearVelocity = Vector2.right * paddleSpeed;
        }

        if (Input.GetKey(KeyCode.A))
        {
            rigidBody.linearVelocity = Vector2.left * paddleSpeed;
        }


        if (Input.GetKey(KeyCode.RightArrow))
        {
            rigidBody.angularVelocity = -paddleRotationSpeed;
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            rigidBody.angularVelocity = paddleRotationSpeed;
        }
    }
}

(I worked out that I needed to use linear damping after a bit of time researching rigidbody2D, sorry for not mentioning)