Constrain velocity on only x & z (let the jump fly free!)

I’m using the oft sited (yet probably ham-handed) method of constraining velocity:

	if (Mathf.Abs (rigidbody.velocity.magnitude) > maxSpeed){
		rigidbody.velocity = rigidbody.velocity.normalized * maxSpeed;
	}

Hopefully I’ll work out something a bit more robust in the future, but for now my main problem is that this formula slows down the vertical motion of my jumps. I only want the magnitude of motion across the ground (x and z axes) to be affected by the velocity constraint, not z motion.

I’ve tried setting an “OnGround” bool to use as a second qualifier for the velocity constraint, which is controlled by the OnCollision trio of functions, but there always seems to be at least a frame after the jump impulse is fired where it still thinks it’s in contact with the ground and thus ruins the jump. Any insight out there?

Assuming you are talking about world directions, you can do it this way:

var v = rigidbgody.velocity;
var f = v.y;
v.y = 0.0;
v = Vector3.ClampMagnitude(maxSpeed);
v.y = f;
rigidbody.velocity = v;

‘maxSpeed’ now represents only ground speed.

Note on your original code. Vector3.magnitude is always positive, so you don’t have to do a Mathf.Abs().

@robertbu got me thinking in a good direction (saving and replacing the y velocity) and I made my own version.

		float saveVelY = rigidbody.velocity.y;
		rigidbody.velocity = new Vector3 (rigidbody.velocity.x, 0.0f, rigidbody.velocity.z);
		rigidbody.velocity = Vector3.ClampMagnitude (rigidbody.velocity,MovementScript.maxSpeed);
		rigidbody.velocity = new Vector3(rigidbody.velocity.x,saveVelY,rigidbody.velocity.z);