Limit player speed (2D)?

Hello, I am prototyping a 2D platforming game for practice. I am working on the player movement and so far I have successfully gotten it to move based on input. However, I am unable to limit the speed. I have tried setting a max speed and changing the velocity to match the max speed if the player’s current velocity exceeds the max speed, but that has not been working. Is there a smooth, clean way to limit the max speed?I have heard about something called clamping, but I am not really sure exactly what it is and how I can use it in this scenario. I am new to programming, especially when it comes to 2D physics. Thanks in advanced.

Here is my current script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
     public float speed;
     public float maxSpeed;
     public bool onGround;
     public Rigidbody2D playerRB;
     private void Start()
     {
         playerRB = gameObject.GetComponent<Rigidbody2D>();
     }
     private void FixedUpdate()
     {
         float x = Input.GetAxis("Horizontal");
         playerRB.AddForce((Vector2.right * speed) * x);
     }
}

You would do it FixedUpdate like this:

private float maxSpeedSqr;

void Awake()
{
      maxSpeedSqr = maxSpeed*maxSpeed;
}

void FixedUpdate()
{
       float velocity = playerRB.velocity;

       // we check versus the squareMagnitude of a Vector
       // to avoid costly square roots
       if (velocity.sqrMagnitude > maxSpeedSqr)
       {
                rb.velocity = velocity.normalized*maxSpeed;
       }
}

FixedUpdate is like Update but its called by the Physics engine at regular fixed intervals. velocity.normalized is just the Vector3 set to magnitude of 1 (but preserving direction) so we can multiply it by our maxSpeed.

I think I read somewhere that Unity recommends against using the method and instead you should calculate a negative force that would exactly set you speed to maxSpeed. But its much more complicated and so far I’ve never had an issue using this, but just letting you know.

I did what you said and no, no matter what the max speed or the speed is set to, the player moves at the same constant (slow) velocity in either direction. This is my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour {

    public float speed;
    public float maxSpeed;
    public float maxSpeedSqr;
    public bool onGround;
    public Rigidbody2D playerRB;

    private void Start()
    {
        playerRB = gameObject.GetComponent<Rigidbody2D>();
        maxSpeedSqr = maxSpeed * maxSpeed;
    }

    private void FixedUpdate()
    {
        Vector2 velocity = playerRB.velocity; // float velocity created errors. Could not set Vector2 as a float

        float x = Input.GetAxis("Horizontal");

        playerRB.AddForce((Vector2.right * speed) * x);

        if (velocity.sqrMagnitude > maxSpeedSqr)
        {
            playerRB.velocity = velocity.normalized * maxSpeed;
        }

    }

}

Ok i’m confused I though you wanted a speed limiter because your player was going too fast? though one problem is you shouldn’t check Input.XXX in FixedUpdate because it might not be valid anymore. Input.GetAxis is only valid in Update during the one frame that the player pressed a key

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
    public float speed;
    public float maxSpeed;
    public float maxSpeedSqr;
    public bool onGround;
    public Rigidbody2D playerRB;
    private bool xPressed;
    private void Start()
    {
        playerRB = gameObject.GetComponent<Rigidbody2D>();
        maxSpeedSqr = maxSpeed * maxSpeed;
        xPressed = false;
    }
    private void Update()
    {
            // Update might run more than 1 time in between
            // Fixed so only add force once
            if(!xPressed)
            {
                 float x = Input.GetAxis("Horizontal");
                 playerRB.AddForce((Vector2.right * speed) * x);
                 xPressed = true;
            }
}
    private void FixedUpdate()
    {
        // reset xPressed so we can handle input in Update
        xPressed = false;

        Vector2 velocity = playerRB.velocity; // float velocity created errors. Could not set Vector2 as a float
        if (velocity.sqrMagnitude > maxSpeedSqr)
        {
            playerRB.velocity = velocity.normalized * maxSpeed;
        }
    }
}