Positions to rotations of a regular GO

Hi,
how could I transfer a hierarchy defined by positions to a hierarchy defined by rotations?

In other words, I have 4 objects defined as follows:

  • GoA
  • GoB
  • GoC
  • GoD

Each with independent coordinates, no rotations.

I would like to get here using rotations so the correction propagate itself using rotations through the hierarchy.

  • GoA
  • GoB

  • GoC

  • GoD

Actually, it is the same thing as bones in 3D models. So, how do I calculate this?

It should be fairly simple math but I can’t figure it out.

If you just want to copy “parent” rotations to the “child” objects without modifying their positions, you could add the following script to each child, then drag the parent object to the parent field in the Inspector:

var parent: Transform;
private var myRot: Quaternion;
private var baseRot: Quaternion;

function Start(){
  baseRot = parent.rotation;
  myRot = transform.rotation;
}

function Update(){
  if (baseRot != parent.rotation){
    transform.rotation = Quaternion.Inverse(baseRot) * parent.rotation * myRot;
  }
}

This script respects the original rotations, and just copies the changes occurred in the parent rotation. Objects can be childed to any level; the only problem is that the Update order may not respect the hierarchy, thus some children may not be rotated in the same frame as their parents - but this only creates a 1 frame lag for each hierarchy level in the worst case. If the hierarchy is A->B->C->D (D is the deepest child), for instance, and the Update order is the exact reverse (D, C, B, A), D will follow A rotation 3 frames after.

Yes that is very simple :smiley:

Unity does this already for you :wink:

If you have 4 GOs in the scene and they already have their desired positions / rotations in the world, just parent them together. Unity will keep the objects world position and orientation. That means .position and .rotation will stay the same but the actual .localPosition and .localRotation will be changed automatically to match the new parent.

A simple example with two object:

GoA: position(10,0,0) rotation(0,90,0) localPosition(10,0,0) localRotation(0,90,0)
GoB: position(10,0,5) rotation(0,0,0)  localPosition(10,0,5) localRotation(0,0,0)

// When you make GoB a child of GoA, like this:
GoB.transform.parent = GoA.transform;
// this happens to the coordinates:

GoA: position(10,0,0) rotation(0,90,0) localPosition(10,0,0) localRotation(0,90,0)
GoB: position(10,0,5) rotation(0,0,0)  localPosition(-5,0,0) localRotation(0,-90,0)

As you can see, the world position will stay the same, but the local position will change. GoB was offset by 5 on the z axis but when it’s a child of GoA it has to be offset by -5 on x because GoA is rotated by 90° and the local x-axis of A points into the negative z-world-axis. Also the rotation of B has changed to revert the rotation it inherits from A.

That’s all a bit messy, just try it yourself. It’s the same when you parent GameObjects in the hierarchy view. The position / rotation you see in the Inspector is the localPosition / localEulerAngles