I need to keep a transform orbiting another transform at an angle determined by me

Hello everyone, I’m a 28 year old game developer, I’m pretty bad at math and geometry, it took over a week for me to work on it, I don’t know much about quaternions, I’m not such a bad developer, but I couldn’t do such a simple thing. I just need to hold an object at a certain angle in the orbit of another object, just like Transform.RotateAround which doesn’t rotate on its own but fixed at the specified angle.

Or it could be something like, a pseudocode that returns CubeB when CubeA rotated like in the gif below. (Unfortunately, in the project I am working on, I do not have a chance to make the orbiting object a child of the central object.)

8414157--1112376--helpgif.gif

I was able to use Transform.RotateAround this way using Quaternion.FromToRotation(for keeping the difference constant), but I have to write all this as a common static method and it gets over-parameterized like “Rotate in this axis, direction of rotation is that direction. etc.”…

Everything I can find on the internet works to automatically rotate the object around another object.

Why not make another empty GameObject the child of the central rotating one, then make the one that are not able to make into a child simply take its position each frame (such as in LateUpdate() ) and move to that position?

Otherwise perhaps make blank GameObject at the center and cause it to always mimic the real central core’s rotation, and child your position to that?

Then let me pry your brain open and fix that!

The math to compute a rotated position is simple enough:

// given this:
Quaternion rotation = ... however you set this
Vector3 center = ... however you set this
float distanceUp = ... however you set this

// then the rotated position is:

Vector3 orbitingPosition = center + rotation * Vector3.up * distanceUp;

That assumes you’re spinning around the Z axis, and that up is the identity rotation.

my goal is to make a static method as I mentioned. In the math you mentioned, we have to choose the distance of the object ourselves and if we write the difference of the object from the center where the distance should be, the object will rotate itself again. Maybe there will be more than one of objects and dealing with each of them is laborious. when we drag the object in the editor and choose its center, the distance should be that. for instance, this is how it is in Transform.RotateAround method.
If we are going to make a static method, it would still not be appropriate to store the difference of the object from the center at the start of the game or the beginning of a coroutine.

The mentioned process can be done as follows

            rot = Quaternion.Inverse(obj.rotation) * center.rotation;
            obj.position = rot * (obj.position - center.position) + center.position;
            obj.rotation = center.rotation;

but there is still a problem, offset needs to be added to the rotation and when the offset is added, the object starts to rotate by itself again.

            *didn't work* Quaternion offsettedRot = offset * point.rotation;
            *didn't work* Quaternion offsettedRot = Quaternion.Inverse(offset) * point.rotation
            *didn't work* Quaternion offsettedRot = offset * Quaternion.Inverse(point.rotation)
            main.position = offsettedRot * (main.position - point.position) + point.position;

            rot = Quaternion.Inverse(main.rotation) * point.rotation;
            *didn't work* rot.eulerAngles += offsetRotation.eulerAngles;
            *didn't work* rot = offsetRotation * rot;
            main.position = rot * (main.position - point.position) + point.position;

            main.rotation = point.rotation;

Any computation that involves reading / writing from .eulerAngles is always going to drift. Here’s why:

All about Euler angles, by StarManta:

https://starmanta.gitbooks.io/unitytipsredux/content/second-question.html

Generally only read ONCE from .eulerAngles, or ideally not at all.

Ok, thanks, I’ve been struggling since yesterday, actually the problem is solved but I couldn’t add offset
By the way, When you said open my brain and fix that, I thought you meant my brain was like broken,(funny thing is I have OCD) I may have a little bit overreacted, excuse me for that…

I think I finally managed to add offset
point is center, main is object in orbit.

            rot = Quaternion.Inverse(main.rotation) * point.rotation;
            offsetRot = Quaternion.Euler(0,0,160);
            Quaternion finalRot = rot * offsetRot;
            main.position = finalRot * (main.position - point.position) + point.position;
            main.rotation = offsetRot * point.rotation;

Another solution, rotation angle to direction, direction can be adjusted as position but works for just 2D games

Vector2 ObjectPosOnOrbit = (/*rotationAngle to Direction*/new Vector2(Mathf.Cos(rotationAngle * Mathf.Deg2Rad), Mathf.Sin(rotationAngle * Mathf.Deg2Rad)) * distanceFloat) + CenterObjectPositionVector3;