# How to apply rotation of pivot to pivoted object?

Consider the following situation:

There are two `GameObject`s :

• `_pivot`
• `_objectToRotate`

`_pivot` is constantly performing some arbitrary rotation around itself.

How would I get `_objectToRotate` to perform exactly “the same” rotation that `_pivot` had performed but around `_pivot` as opposed to around itself?

Essentially, `_pivot` would act as a pivot for `_objectToRotate`. But also their orientations should align. Say, if `_pivot.transform.forward == _objectToRotate.transform.forward` before the rotation, then `_pivot.transform.forward == _objectToRotate.transform.forward` after the rotation.

The following code solves this problem if `_pivot`’s rotation is known:

``````// apply some rotation to _pivot
_pivot.transform.RotateAround(_pivot.transform.position, new Vector3(1, 1, 1), 90 * Time.deltaTime);
// apply the desired "pivoted" rotation to _objectToRotate
_objectToRotate.RotateAround(_pivot.transform.position, new Vector3(1, 1, 1), 90 * Time.deltaTime);
``````

But how do I do this dynamically if I don’t know `_pivot`’s rotation?

Storing `_pivot`’s forward vector inside `pivotForwardLastUpdate`, I came very close to solving this, using the following snippet:

``````// determine _pivot's rotation around the axes since last update
float xRotationSinceLastUpdate = Vector3.SignedAngle(_pivot.transform.forward, pivotForwardLastUpdate, Vector3.right);
float yRotationSinceLastUpdate = Vector3.SignedAngle(_pivot.transform.forward, pivotForwardLastUpdate, Vector3.up);
float zRotationSinceLastUpdate = Vector3.SignedAngle(_pivot.transform.forward, pivotForwardLastUpdate, Vector3.forward);
// apply _pivot's rotation since last update to _objectToRotate (around the axes)
_objectToRotate.RotateAround(_pivot.transform.position, Vector3.right, -xRotationSinceLastUpdate);
_objectToRotate.RotateAround(_pivot.transform.position, Vector3.up, -yRotationSinceLastUpdate);
_objectToRotate.RotateAround(_pivot.transform.position, Vector3.forward, -zRotationSinceLastUpdate);
``````

This makes `_objectToRotate` move along the correct trajectory with the correct orientation. But it moves along the trajectory faster than `_pivot` for some reason.

I’ve been struggling with this all day - help is much appreciated!

That being said, it’s also possible with a little bit of quaternion math I think that should do what you want :

``````void Update()
{
Quaternion rotation = pivot.rotation * Quaternion.Inverse(oldOrientation);

float angle = Mathf.Acos(rotation.w) * 2;
Vector3 axis = new Vector3(rotation.x, rotation.y, rotation.z).normalized;

oldOrientation = pivot.rotation;
}
``````

Or another way that relies on the initial orientation instead of the one from the previous frame (to avoid any floating point errors or things like that) :

``````public class TestRotation : MonoBehaviour
{
public Transform pivot;
private Quaternion frameOrientation;
private Quaternion identityPoint;

private void Start()
{
frameOrientation = Quaternion.Inverse(pivot.rotation) * transform.rotation;
Vector3 position = transform.position - pivot.position;
identityPoint = Quaternion.Inverse(pivot.rotation) * new Quaternion(position.x, position.y, position.z, 0) * pivot.rotation;
}

void Update()
{
transform.rotation = pivot.rotation * frameOrientation;
Quaternion position = pivot.rotation * identityPoint * Quaternion.Inverse(pivot.rotation);
transform.position = pivot.position + new Vector3(position.x, position.y, position.z);
}
}
``````

If the usecase allows for it, a workaround for this problem is to temporarily set `_pivot` as the parent of `_objectToRotate` by calling `_pivot.transform.SetParent(_objectToRotate.transform, true)`.
Make sure to set the `worldPositionStays` flag of Transform.SetParent() if you want to prevent position changes before/after setting the parent.

I think the best way is to have `_objectToRotate` be a child of `_pivot`, this way when you rotate `_pivot`, Unity handles the math for rotating and moving `_objectToRotate`.

If it’s not possible, then add an empty object as a child of `_pivot` and set the rotation and position of `_objectToRotate` to the same as that empty object in `Update()` 