Stop and object from moving faster after a specific speed is reached?

(I use C#. (The master race of code.))

So, i’ve making another simple game since it’s been awhile since i’ve used Unity. And to put it simply, I’m actually having fun with it! :smiley: However, I’ve searched the Documentation and Scripting API for a while now, and I still haven’t found a real good answer for a little problem I have. Maybe one of you coding deities could lend me a hand, or at least point me to a webpage, that would be awesome!.

This is the situation. I have a little cube named “Player”, and it moves forward at a set speed. I made the script in the only way I know how (because I’m still a n00b at C#), which is by getting the Rigidbody of the player and using Rigidbody.AddForce with the FixedUpdate function (I’ve been told that using FixedUpdate is good for physics code). The problem is, the cube lands on the ground, speeds up, but never slows down, until it reaches light-speed. For my game to actually be playable, I need the cube to just stop moving so fast and stop speeding up once it has reached a certain velocity, and stay at that velocity.

PS. This isn’t exactly necessary, but it would be neat to use. If any of you know how to disable a function, in my case my update function for movement, once a bool becomes true, that would be great to know as well.

Here’s the code :

public class PlayerMovement : MonoBehaviour {



	public Rigidbody rb;
	public int playerMovementSpeed;
	public int forwardSpeed;

	// Update is called once per frame
	void FixedUpdate () {
		rb.AddForce (0, 0, forwardSpeed);
		if (Input.GetKey (KeyCode.D)) {
			rb.AddForce (playerMovementSpeed, 0, 0);
			} 
		else if (Input.GetKey (KeyCode.A)) {
			rb.AddForce (-playerMovementSpeed, 0, 0);
			} 
			// I want to put my " Stop-speeding up " code here.
		}
	}

You can simply add this line at the end of your FixedUpdate method:

rb.velocity = Vector3.ClampMagnitude(rb.velocity, MaxVelocity);

Of course “MaxVelocity” is a float value indicating your max velocity. Note that it clamps the absolute velocity and not on a “per axis” basis. This is usually what you want. It prevents the user from gaining speed by running forward and strafing left or right. Though it also takes the y-speed into account. If you want to ignore the y-speed and only clamp the x-z-speed you can do:

Vector3 v = rb.velocity;
v.y = 0;
v = Vector3.ClampMagnitude(v, MaxVelocity);
v.y = rb.velocity.y;
rb.velocity = v;

Or without ClampMagnitude:

Vector3 v = rb.velocity;
float speed = Mathf.Sqrt(v.x*v.x + v.z*v.z);
v.x /= speed; // normalize x-z-speed vector
v.z /= speed;
if (speed > MaxVelocity) // clamp the current speed
    speed = MaxVelocity;
v.x *= speed; // scale the x-z-speed by the clamped speed
v.z *= speed;
rb.velocity = v;

You can add an if check on the rigidbodies velocity and if it exceeds your ‘max speed’ then don’t add any more force.

As for ‘disabling’ the Update function you can just have a bool check to return or not like so:

private bool isUpdateDisabled = false;

void FixedUpdate () {
     if (isUpdateDisabled){
          return;
     }
}

So when isUpdateDisabled is true the function will return immediately and not execute anything below it.