# ClampMagnitude -- why no minimum?

I’m applying both positive and negative forces to a rigidbody, but I need a minimum and maximum speed.
ClampMagnitude allows me to specify a maximum, but not a minimum.

Is there a reason for this?

It’s easy enough to do it myself, of course, I’m just curious.

``````if (rigidbody.velocity.magnitude < minVelocity) rigidbody.velocity = rigidbody.velocity.normalized * minVelocity;
``````

I assume internally ClampMagnitude does exactly this but using a greater-than operator.

First, here’s ClampMagnitude:

``````    /// <summary>
///
/// <para>
/// Returns a copy of vector with its magnitude clamped to maxLength.
/// </para>
///
/// </summary>
/// <param name="vector"/><param name="maxLength"/>
public static Vector3 ClampMagnitude(Vector3 vector, float maxLength)
{
if ((double) vector.sqrMagnitude > (double) maxLength * (double) maxLength)
return vector.normalized * maxLength;
return vector;
}
``````

Note, it uses sqrMagnitude because it’s faster.

As for why it’s only has the max… who knows. Unity engineers probably just didn’t bother to put it in.

Why do they clamp lerps to a t value of 0->1, and then have an ‘LerpUnclamped’?

They make weird decisions for their own reasons.

Write a custom ‘ClampMagnitude’ that accepts both a min and a max…

``````public static Vector3 ClampMagnitude(Vector3 v, float max, float min)
{
double sm = v.sqrMagnitude;
if(sm > (double)max * (double)max) return v.normalized * max;
else if(sm < (double)min * (double)min) return v.normalized * min;
return v;
}
``````
8 Likes

Yeah I did write my own, though this n00b often forgets sqrMagnitude.

Maybe I have actually stumbled into an explanation (although it’s probably just coincidence).

I’m clamping the magnitude of a Rigidbody’s velocity in a system which applies positive and negative values for AddForce. These forces should (in theory) bring the forward vector into alignment with the velocity vector, and also to reduce forward motion when the object is changing direction. In this particular case, clamping the maximum is always ok, but blindly clamping the minimum means the Rigidbody can’t reverse direction. Reversing direction is necessary when the velocity vector is more than 180 degrees out of alignment with the forward vector (e.g. the object ends up moving backwards), as can happen immediately after extremely sharp turns. My current approach is to clamp the minimum only when the forward and velocity vectors are aligned in a forward direction (dot product > 0).

I suppose it’s unlikely that this narrow case would be the reason for the API to only clamp the maximum, but I can see how a blanket clamp on the minimum could cause trouble from time to time, whereas a maximum clamp is probably fairly foolproof.

The Lerp clamp makes plenty of sense to me. It goes without saying that interpolation doesn’t work without a known range and a percentage (float 0-to-1) is an obvious and simple way to generically represent progress over any range of values, especially in the “floats everywhere” world of Unity…

old but still thank you, this was doing my head in, i couldn’t figure out how to set a min for it

since this thread is already resurrected I guess I could also throw in my opinion for why ClampMagnitude doesn’t have a “min” value: There is no reasonable answer to what ClampMagnitude should output if the input Vector3 is (0,0,0).

1 Like

While true, this is also true for many other methods involving vectors, such as .Normalize() or Quaternion.LookRotation().

1 Like