How to keep an object within a circle/sphere (radius) - NO RECTANGLE

To limit movement in a rectangle, it is easy

        if (newLocation.x > maxPosition)
        {
            newLocation.x = maxPosition;
        }
        else if (newLocation.x < -maxPosition)
        {
            newLocation.x = -maxPosition;
        }

        if (newLocation.z > maxPosition)
        {
            newLocation.z = maxPosition;
        }
        else if (newLocation.z < -maxPosition)
        {
            newLocation.z = -maxPosition;
        }

However, whenever you want to keep these boundaries in a CIRCLE, rather than a RECTANGLE, it becomes mathematically complex (for those like me who haven’t taken a math course in over a decade).

How do I limit movement in a circle, rather than a rectangle? Unity’s functions don’t see to help. I even tried complex things like using a SphereCollider and ClosestPointOnBounds (which returns for a rectangle…even when used with a SphereCollider)

Alt text

float radius = 400; //radius of *black circle*
Vector3 centerPosition = transform.localPosition; //center of *black circle*
float distance = Vector3.Distance(newLocation, centerPosition); //distance from ~green object~ to *black circle*

if (distance > radius) //If the distance is less than the radius, it is already within the circle.
{
Vector3 fromOriginToObject = newLocation - centerPosition; //~GreenPosition~ - *BlackCenter*
fromOriginToObject *= radius / distance; //Multiply by radius //Divide by Distance
newLocation = centerPosition + fromOriginToObject; //*BlackCenter* + all that Math
}

If the distance is < radius, it is within the circle. No need for any calculations.
If the distance is > radius, the object is outside the circle.

  1. Determine the center position of the circle/radius. The radius of this circle is also the maximum limit.
  2. Determine the distance between point A (circle/bounds) and B (object you want to limit; prevent movement outside of bounds A).
  3. If the distance is greater than the radius, then do the following:
  4. Get Vector3 U from B (object) minus A (circle).
    (U = B - A)
  5. Multiply by Radius
    (U x Radius)
  6. Divide by Distance
    (U / Distance)
  7. Position = U + A (maxLocation = U + A)

Well, don’t use max / min positions as they define a rectangle. What you want is defining a center point and a radius. Then just use Vector3.ClampMagnitude on the relative vector:

// C#
Vector3 v = newLocation - circleCenter;
v = Vector3.ClampMagnitude(v, circleRadius);
newLocation = circleCenter + v;

If the circle center and your location is not on the same “height” (y value) you can do:

// C#
circleCenter.y = newLocation.y;
Vector3 v = newLocation - circleCenter;
v = Vector3.ClampMagnitude(v, circleRadius);
newLocation = circleCenter + v;

Hi,
I would simply check the distance.
I´m correct in the assumption, that we´re in the two-dimensional-space?

Vector2 center;
Vector2 position;
float maxDistance;

float actualDistance = Vector2.Distance(center, position);

if (actualDistance > maxDistance)
{
    Vector2 centerToPosition = position - center;
    centerToPosition.Normalize();
    position = center + centerToPosition * maxDistance;
}