Is this alright as a movement script?

Hello!
I was always unsure about how to use fixedupdate correctly, now I’m trying to make a 2D platformer and I want to movement system to be as polished as possible, so I made a simple movement script but I’m not sure if I use fixedupdate correctly here. Do I? If not what should I do?

    [SerializeField] private float speed = 2f;
    [SerializeField] private float maxSpeed = 6f;
    [SerializeField] private float friction = .15f;

    private Vector2 currentVelocity = Vector2.zero;
  
    private Rigidbody2D myRb;
  
    private float xInput, yInput;

    void Start()
    {
        myRb = GetComponent<Rigidbody2D>(); 
    }

    void Update()
    {
        GetInput();
    }

    private void GetInput()
    {
        xInput = Input.GetAxis("Horizontal");

        //Calculating velocity
        if (Mathf.Abs(currentVelocity.x) < maxSpeed)
        {
            Vector2 newVelocity = new Vector2(xInput, myRb.velocity.y) * speed * Time.deltaTime;
            currentVelocity += newVelocity;
        }

    }

    private void FixedUpdate() {
        UpdateVelocity();
    }

    private void UpdateVelocity()
    {      
        //Friction
        if (Input.GetAxisRaw("Horizontal") == 0 || (xInput > 0 && myRb.velocity.x < 0) || (xInput < 0 && myRb.velocity.x > 0))
        {
            currentVelocity.x = Mathf.Lerp(currentVelocity.x, 0f, friction);
        }

        currentVelocity.x = Mathf.Clamp(currentVelocity.x, -maxSpeed, maxSpeed);
    }

       myRb.velocity = currentVelocity;

I noticed a little mistake but unity forums wont let me edit the post as it is “Spamming” as it believes so I just post the correct code in a reply

    [SerializeField] private float speed = 2f;
    [SerializeField] private float maxSpeed = 6f;
    [SerializeField] private float friction = .15f;

    private Vector2 currentVelocity = Vector2.zero;
 
    private Rigidbody2D myRb;
 
    private float xInput, yInput;

    void Start()
    {
        myRb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        GetInput();
    }

    private void GetInput()
    {
        xInput = Input.GetAxis("Horizontal");

        //Calculating velocity
        if (Mathf.Abs(currentVelocity.x) < maxSpeed)
        {
            Vector2 newVelocity = new Vector2(xInput, myRb.velocity.y) * speed * Time.deltaTime;
            currentVelocity += newVelocity;
        }

    }

    private void FixedUpdate() {
        UpdateVelocity();
    }

    private void UpdateVelocity()
    {    
        //Friction
       if (Input.GetAxisRaw("Horizontal") == 0 || (xInput > 0 && myRb.velocity.x < 0) || (xInput < 0 && myRb.velocity.x > 0))
        {
            currentVelocity.x = Mathf.Lerp(currentVelocity.x, 0f, friction);
        }

        currentVelocity.x = Mathf.Clamp(currentVelocity.x, -maxSpeed, maxSpeed);

        myRb.velocity = currentVelocity;
    }

You should be using xInput instead of Input.GetAxisRaw on line 41, but otherwise it’s pretty good.

1 Like

Does it work? Then ship it. :slight_smile:

If you like some feedback, gather ALL the input in one function. You’re actually gathering input from the same axis in two places.

ALSO: GetAxisRaw() might never actually return zero. It might drop to 0.0001 and never fire those lines of code. Instead, check for something like Mathf.Abs( xInput) < 0.1f as a condition.

1 Like

@Kurt-Dekker
@StarManta

There seems to be a problem after all.
Lines 28. 29. messes up the player’s y movement. I want this not to affect the y velocity at all, but it does and weird behaviour happens. On line 28. I’ve tried changing myRb.velocity.y to 0f but it stops the player in the air, which is quite odd because logically for me if you add 0 to something it shouldn’t affect it at all.

How could I change my code so the Y velocity won’t be affected?

I think i found a solution

        //Calculating velocity
        if (Mathf.Abs(currentVelocity.x) < maxSpeed)
        {
            Vector2 newVelocity = new Vector2(xInput, 0f) * speed * Time.deltaTime;
            currentVelocity += newVelocity;
            currentVelocity.y = myRb.velocity.y;
        }