transform.RotateAround distance from object not constant?

I’m rotating my camera around my character about the y axis. I want to stop the camera from rotating after it has rotated x° so I’m doing some math to figure out how many degrees around the object the camera has traveled by keeping track of the start position and the current position. Here’s the problem I’m having, for my math to work I need the camera to always be the same distance from the object it’s rotating around (radius of the circle has to stay constant). But when I use the Vector3.Distance function to see the distance of the camera from the object it returns different values. I would appreciate help in figuring out why this is happening because the math won’t work if the camera isn’t rotating around my object along a circular pattern.

Here’s my code:

// this value is changing between frames
var radius = Vector3.Distance(_rotationSpotlight.Value, transform.position);

var distanceBetweenPointsOnCircle = Vector3.Distance(transform.position, _spotlightRotationStartingPoint);

// this at times returns float.NaN because my radius is changing and my transform.position isn't staying in a circular rotation.
var theta = Mathf.Acos(

    (2 * Mathf.Pow(radius, 2) - Mathf.Pow(distanceBetweenPointsOnCircle, 2))
    /
    (2 * Mathf.Pow(radius, 2)));

var degrees = theta * 57.2958;
}

I’m normalizing all of my vectors too but not really sure what that does or if I’m supposed to be doing that. The docs say normalizing removes the magnitude but I don’t understand how magnitude can even be embedded in x,y,z positional values.

Oh, and here’s the code that’s rotating my camera around the object. Just the standard transform.RotateAround.

transform.RotateAround(_rotationSpotlight.Value, _rotationAxis.Value, 50 * Time.deltaTime);

Appreciate the help!

If you have a vector (10, 0, 0) and you normalize it, it becomes (1, 0, 0), so magnitude 10 becomes 1.

But at least i’m having some trouble getting the idea through. You didn’t show all the code related to the variables you are showing. Like you show “degrees”, but it isn’t used anywhere?

Here’s my version for orbiting:

using UnityEngine;

public class Test : MonoBehaviour {

    public Transform orbiter;
    public float TargetDistance;

    void Update() {
        orbiter.RotateAround(transform.position, transform.up, 10f * Time.deltaTime);
        Vector3 delta = orbiter.position - transform.position;
        delta.y = 0; // Keep same Y level
        orbiter.position = transform.position + delta.normalized * TargetDistance;
    }
}

Degrees is the result. That’s the end of the problem. Once I have degrees calculated correctly I’m done. Here’s how I’m using it though:

if (degrees >= maximumRotation)
{
    // stop rotating
    _rotationSpotlight = null;
}

I’m not having a problem rotating around an object. I need to know how to determine when I have completed x° in the rotation so that I know when to stop.

You can use this function for example:

        public static float Angle2(Vector2 a, Vector2 b) {
        return Mathf.Atan2(b.y-a.y, b.x-a.x) * 180f / Mathf.PI;
    }

Using transform.position and orbiter.position as parameters. If it’s X,Z plane then you need to make new vectors where Y is Z. Track the value each frame, and when it changes in specific way, it completed full round.

edit: Oh and one thing we have to be clear on. What should be happening when main object is moving at high speed to some direction? The orbiting object will keep following at set distance but not able to keep up with the rotation, or that it will always rotate at stable rate no matter the speed?

Because if it’s the latter, this is a much simpler problem where you can have
float angle; where if angle > 360 it has rotated full circle. Setting position of orbiter with

angle += Time.deltatime * rotationspeed;
delta.x = Mathf.Cos(angleMathf.Deg2Rad) * TargetDistance;
delta.z = Mathf.Sin(angle
Mathf.Deg2Rad) * TargetDistance;
orbiter.position = transform.position + delta;

Or even 3rd option that it can orbit in 3 dimensions, would make this a more complex issue.

Yeah, the object I’m orbiting will not be itself moving. I did end up getting my code to work before I saw your answer although your answer looks promising. Here is what I ended up doing.

var radius = Vector3.Distance(_rotationSpotlight.Value, transform.position);

var distanceBetweenPointsOnCircle = Vector3.Distance(transform.position, _spotlightRotationStartingPoint);

var theta = Mathf.Acos(Mathf.Max(-1,

    (2 * Mathf.Pow(radius, 2) - Mathf.Pow(distanceBetweenPointsOnCircle, 2))
    /
    (2 * Mathf.Pow(radius, 2))));

var degrees = theta * 57.2958;

if (_spotlightRotationStartingPoint.x < transform.position.x)
{
    degrees += 180;
}

The only issue I have is that I have to use Mathf.Max(-1, …) to prevent the code from passing a value < -1 to Acos (which results in float.NaN. I’m not sure why the calculations can result in a value < -1 but I’m not looking into it further ATM.