How do I rotate a game object around a custom pivot?
A popular answer is to use transform.rotateAround, but I want to set certain angles rather the adding rotation. Could not find any good solutions for this :(
@trsh I've update my answer to you a few times because I had to rethink - doing this off the top of my head.
Answer by streeetwalker · Apr 09, 2020 at 09:12 AM
HI @trsh, I've updated this because I had to re-think, again! The general problem is you need to get th object back to it's zero rotation. Here is the simplest solution yet
1. get the offset distance to the pivot
distance = (object pos - pivot pos).magnitude
2. move the object back to it's zero rotation - you have to decide
what axis that is on - here, I'm using World Positive Right axis
object pos = pivot pos + Vector3.right * distance
After doing that, the object has been moved back to it's zero rotation with respect the pivot. Then apply your desired angle to RotateAround
Previous solutions: In order to start from zero, You'll have to calculate the offset angle back what ever axis you consider zero rotation, and the rotateAround using the inverse that angle first ; Then rotateAround will start from no rotation.
What rotateAround does is this:
1. get the desired rotation as a quaternion
2. get the object offset vector to the pivot:
offset vector = object pos - pivot pos
3. Rotate the offset vector
rotated vector = offset vector * desired rotation
4. Move the object to new offset
object pos = rotated vector + pivot pos
So you see, because you use a quaternion multiplication to rotate the offset, which has the affect of taking the current rotation (already represented in the offset vector) and applying the new rotation, you will still need zero out the current rotation before doing all that.
So to calculate the inverse angle you need to apply - let us say positive x is the axis you consider zero:
1. direction vector = object pos - pivot pos
2. inverse angle = Vector3.Angle( direction vector, Vector3.up* )
3. the apply the ***negative of inverse angle to rotateAround
** you need to decide what frame of reference you are using World or local
Vector3.up is the World frame on the Y axis in 3D
*** whether or not you need to apply the negative of the angle depends on the
order of the parameters in Vector3.angle
I believe you can shortcut the process by taking the result of 2 above, convert it to a quaternion, and multiplying your desired rotation by the Quaternion inverse of it, but I'd have to think about that further.
I believe that corrects everything I wrote before!