Rotating a parent object to achieve a specific child rotation.

Alright so I have kind of a weird problem. I need to rotate a parent object in order to orient a child object to a specific direction.

I’m working in VR which means my child object is tracked and I can’t fuck with its rotation in any way, I can only rotate the parent object. Now I need to align this child object to some variable direction at runtime by changing the parent orientation.

This would be pretty easy if I could unparent the child or rotate the child but neither are options. I also have to use a quaternion method of some kind to get a smooth rotation.

So far I’ve had zero luck managing to make this happen though so any help would be appreciated. I imagine this ought to be fairly easy to do with the right knowledge of quaternion math but I haven’t had any luck working it out over the last day.

Ok, I’m pretty sure I’ve solved this for those questing for quaternion rotation solutions in the future.

If you have a look rotation for the direction and alignment you want your child object to have (or any equivalent quaternion) you take the inverse of the child object’s rotation times the look rotation (quaternion subtraction) like so:

lookRotationVar = lookRotationVar * Quaternion.Inverse(childObject.transform.rotation);

then you need to add that look rotation to the parent object’s rotation

lookRotationVar = lookRotationVar * parentObject.transform.rotation;

Now lookRotationVar will be the rotation you want to rotate your parent object towards in order to correctly orient your child object.

At the very least, this has worked through all my testing so far. In particular though I’ve only tested this working with steamVR and having the camera be the child object.

I had a similar yet different scenario that this helped me with - figured I’d share:

I’m working on an inverse kinematic that allows the arms to be positioned wherever then it sets the joint’s position/rotation to be relative to the arm positions

(the joint is represented as Plane)

The arms are represented by vector1 and vector2 (calculated elsewhere and passed to this code)

Since the arm positions are fuzzy relative to the parent joint, I’m taking the bisecting line and cross product as my two vectors that will control the rotation

---------- Initialize

public GameObject Plane;
private Quaternion _delta;

Vector3 bisect = Math3D.GetAverage(new[] { vector1, vector2 }).normalized;
Vector3 orth = Vector3.Cross(bisect, vector1).normalized;

Quaternion bisectRot = Quaternion.LookRotation(bisect, orth);

_delta = bisectRot * Quaternion.Inverse(Plane.transform.rotation);

---------- Update

Vector3 bisect = Math3D.GetAverage(new[] { vector1, vector2 }).normalized;
Vector3 orth = Vector3.Cross(bisect, vector1).normalized;

Plane.transform.rotation = Quaternion.LookRotation(bisect, orth) * _delta;

So in these pictures, the orange lines are the arms, the purple are the bisector and orthogonal

(I placed the arms on the plane to help debugging and visualization, but this works for any initial positions)