Moving one object around another in a circular fashion

Godot Version

4.2.2.stable.mono

Question

Hello everyone, I am trying to get an object in my game to move around another object in a circular fashion. I am trying to do this by adding the vector to the right of object 1 to the vector pointing toward object 2. However I am a bit confused on how to do this. If I rotate Vector3.Right by the Y rotation like

Vector3.Right.Rotated(GlobalTransform.Basis.Y.Normalized(), Rotation.Y) 

will this give me the vector to the right (locally) of object one?

Anyway I hope that makes sense. I’m confused about it so if I’m asking the wrong question I apologize. Feel free to answer in GDScript or in terms of 2D if don’t work in C# or 3D.

From what I’ve just checked, .rotated() returns a new rotated vector without changing the old one. I’d think of it like this: the function is called rotated() (noun), not rotate() (action) . Is your issue that line above does nothing?

Also it depends on what you want to do with the rotating object. If you just need it spinning, maybe you can make it a simple animatable body as a child of a Node3D which rotates. Animatable bodies can be moved manually while affecting physics objects in their path, unlike a static body.

Otherwise if you need to rotate in code, I would probably do something like this:

  1. Get a vector between objects by subtracting their positions. There might be a helper function that gets a vector between points but idk. Then you can get the raw distance if u need it from the magnitude.

  2. Get a new vector. Either specify a new angle such as Rotation.Y, or add to the current one. You can specify a new angle by getting a normalised 3D vector in the direction you want and multiplying it by the aforementioned distance. If you want to change the angle by some amount (consider delta time), rotate the old vector by an angle along the global vertical axis. Make sure to use the returned value, as the function doesn’t modify the original vector.

  3. Apply the new vector!

I just reread your question and I’m sorry I didn’t answer it directly.

I think if you rotate a vector by an object’s own rotation, then yes, the vector will “stick” to the object and be local.

If you want to spin your object by moving it in that direction orthogonal to the centre, it might not work great. It works in real life physics, but since game physics are discrete, that direction is not going to rotate while it moves. The object will spiral out as it steps, depending on frame rate. If you want to do this method, you might want to clamp the distance between the objects afterwards too.

Thank you for the reply! So I believe that Transform.Basis.X is giving me the vector that I want (a vector relative to the right of the object). Using DirectionTo() from the position of object 1 (the object that will rotate around object 2) to object two, get a Vector3 from object 1 to object 2. Then if you add Transform.Basis.X to the vector from DirectionTo() that creates a vector pointing in between Transform.Basis.X and DirectionTo(). If the direction that object 1 is moving toward is the sum of Transform.Basis.X and DirectionTo(), with the correct velocity, Object 1 with circle around object 2.

Again I am sorry if my question was confusing. If you see a better way that this to achieve encircling behavior go ahead a give me a reply, or if you have any questions about what I said.

Thanks again!

Well does it work?

Don’t forget to apply a rotation to the orbiting object, else it’s right basis vector will never change, and it will shoot off in a straight line.

Like I said though, this method will cause the orbit to spiral out over time, because you are approximating it with straight line segments without accounting for how those go outside the circle slightly each time. If you want to do this, you need to constrain the distance between the nodes.

After applying the basis vector, get a vector from the central body to the orbiting body. Normalise it, then multiply it by the intended orbit radius that you started off with, which you should record as a constant. Then make the global position of the orbiting body that of the central body plus the vector. This will clamp the distance but maintain direction.

Why do you want to do it in code, instead of making the orbiting body part of another Node3D and then rotating that? It would be much simpler to get constant rotation.

Sorry, didn’t see this reply. Yes it works for my case which isn’t exactly orbiting I didn’t explain it very well. Thank you for the insight I was able to find the bug with it!