- Home /
How to limit the force from player input without limiting speed
I want to stop the player from moving the Rigidbody faster than the speed limit, but I don't want to limit the rigidbody speed, so that the Rigidbody can go faster than the speed limit when on ice or when being launched in a ramp. I had one soluting that I didn't like too much and I'm looking for other solutions, here it is:
input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
if (Mathf.Abs(rb.velocity.x) > maxSpeed | Mathf.Abs(rb.velocity.z) > maxSpeed)
{
input = Vector2.ClampMagnitude(input, 0);
}
else
{
input = Vector2.ClampMagnitude(input, 1);
}
I dislike this solution because it messes with the movement, the max speed is never correct and floats too much, this solution overall feels like a work around. For those who know, think of CS:GO movement, where while holding a knife, the max speed is 250, but that doens't stop the player from surfing at thousands of units per second.
Answer by sacredgeometry · Dec 29, 2020 at 05:34 AM
Why do you need to limit the speed in that case? Its only ever going to go as fast as you have told it to go. So tell it to go slower and let the physics engine solve for the other cases.
Well, I'm using AddForce to move the object, and my guess would be that while I keep adding force with the input, the speed is going to keep increasing.
Would you suggest that I try to move my object (Player) without AddForce?
Answer by Eno-Khaon · Dec 29, 2020 at 08:20 PM
While this approach isn't perfect and doesn't properly enforce reaching a top speed, it will still allow you to maintain a high speed without completely giving up control:
// Get the current velocity and flatten it onto movement axes
Vector3 lastFlatVel = rb.velocity;
lastFlatVel.y = 0f;
// Apply player input force(s), then get the flattened vector for the result
rb.AddForce(inputForce, ForceMode.Acceleration); // Or similar
Vector3 flatVel = rb.Velocity;
flatVel.y = 0f;
if(flatVel.sqrMagnitude > maxSpeed * maxSpeed)
{
// Can be combined -- This is easier to read in the webpage
if(flatVel.sqrMagnitude > lastFlatVel.sqrMagnitude)
{
// Store the current vertical speed to insert
// after making flattened changes
float currentY = rb.velocity.y;
// Avoid square root calculations unless this specific condition is met
rb.velocity = flatVel.normalized * lastFlatVel.magnitude;
rb.velocity.y = currentY;
}
}