Vector3 Clamp

I tried limiting a Vector3 with Mathf.Clamp, but it caused a jittery effect on the gameobject.

Note: This is not C# but now obsolete (JS-like) Unity Script.
public var moveSpeed : float;
public var minimumX : float;
public var maximumX : float;
public var minimumY : float;
public var maximumY : float;
public var resetTimerX : float;
public var resetTimerY : float;
public var defaultPos : Vector3;
public var newPos : Vector3;
  
function Start() {
	defaultPos = gameObject.transform.localPosition;
	newPos = gameObject.transform.localPosition;
}
  
function Update() {
	newPos.x += Input.GetAxis("Mouse X") * moveSpeed * Time.deltaTime;
	newPos.y += Input.GetAxis("Mouse Y") * moveSpeed * Time.deltaTime;
	gameObject.transform.localPosition = newPos;
	newPos.x = Mathf.Clamp(newPos.x, minimumX, maximumX);
	newPos.y = Mathf.Clamp(newPos.y, minimumY, maximumY);
}

I found that it’s the Clamp causing this. Can Vector3’s not be clamped?
What other meathods can be used to limit position?

Sure there’s a jitter since you clamp after you assigned the values…

So the change that happens in the current frame is always transferred to the objects position. You have to clamp before you assign the position to the object.

Note: This is not C# but now obsolete (JS-like) Unity Script.
function Update()
{
    newPos.x += Input.GetAxis("Mouse X") * moveSpeed * Time.deltaTime;
    newPos.y += Input.GetAxis("Mouse Y") * moveSpeed * Time.deltaTime;
    newPos.x = Mathf.Clamp(newPos.x, minimumX, maximumX);
    newPos.y = Mathf.Clamp(newPos.y, minimumY, maximumY);
    gameObject.transform.localPosition = newPos;
}

Hey Corey,

The reason for this is probably coming form interference of other scripts on the position of this object.

Make sure that movement of this object is handled only from one script, and preferably one function.

Also, keep in mind that if you make the object move with physics (ie have a rigid body and apply force etc.) Messing with that object’s movement in scripts will cause jitters.

This is because the physics engine is trying to move it at the same time as your are.

Hope this helps, Alex

/// <summary>
/// Simple helper to clamp a range to vector3
/// </summary>
public class Vector3Range
{
    public Vector3 Min;
    public Vector3 Max;

    /// <summary>
    /// Clamp a range
    /// </summary>
    public Vector3 Clamp(ref Vector3 value)
    {
        value.x = Mathf.Clamp(value.x, Min.x, Max.x);
        value.y = Mathf.Clamp(value.y, Min.y, Max.y);
        value.z = Mathf.Clamp(value.z, Min.z, Max.z);
        return value;
    }
}

For most usages you would want a simple static with min and max as parameters rather than a class but I had a use.

Here’s some extension methods to easily Clamp all Vector3 axes that may be useful to future readers. You can either pass floats or Vector3’s as the min/max. Unrelated to the main issue.

Note:

This doesn’t modify the passed in Vector3, but rather returns the clamped result.

public static Vector3 Clamp(this Vector3 value, float min, float max)
{
    if (value.x < min || value.y < min || value.z < min ||
        value.x > max || value.y > max || value.z > max)
    {
        value.x = Mathf.Clamp(value.x, min, max);
        value.y = Mathf.Clamp(value.y, min, max);
        value.z = Mathf.Clamp(value.z, min, max);
    }

    return value;
}
public static Vector3 Clamp(this Vector3 value, Vector3 min, Vector3 max)
{
    if (value.x < min.x || value.y < min.y || value.z < min.z ||
        value.x > max.x || value.y > max.y || value.z > max.z)
    {
        value.x = Mathf.Clamp(value.x, min.x, max.x);
        value.y = Mathf.Clamp(value.y, min.y, max.y);
        value.z = Mathf.Clamp(value.z, min.z, max.z);
    }

    return value;
}

Sorry for the necro, but I found this question via google while looking for something similar, figure it may help others who stumble upon this thread.