# Manual parenting

I am trying to do parenting by math rather then using the build in parenting function. It kind of works but it is not totally accurate with rotations so the math is wrong. Any help? Here is my code:

``````//caclulate the rotational difference from A to B
public static Quaternion SubtractRotation(Quaternion B, Quaternion A){

Quaternion C = Quaternion.Inverse(A) * B;
return C;
}

//This function uses math for object parenting instead of using the Unity buildin parenting feature.
//Input: parentRotation and parentPosition: the current parent transform.
//Input: startParentRotation and startParentPosition: the transform of the parent object at the time the objects are parented.
//Input: startChildRotation and startChildPosition: the transform of the child object at the time the objects are parented.
//Output: childRotation and childPosition.
//All transforms are in world space.
public static void TransformWithParent(out Quaternion childRotation, out Vector3 childPosition, Quaternion parentRotation, Vector3 parentPosition, Quaternion startParentRotation, Vector3 startParentPosition, Quaternion startChildRotation, Vector3 startChildPosition){

childRotation = Quaternion.identity;
childPosition = Vector3.zero;

Quaternion relativeRotation = SubtractRotation(startChildRotation, startParentRotation); //TODO: this does not have to be done each frame.
childRotation = parentRotation * relativeRotation;

//Set the position which is the result of parent rotation
Quaternion childRotationDifference = SubtractRotation(childRotation, startChildRotation);
Vector3 parentToChildVector = startChildPosition - startParentPosition;
Vector3 rotatedVector = childRotationDifference * parentToChildVector; //Rotate a vector with a quaternion
rotatedVector += startParentPosition;

//Add the position which is the result of parent translation
Vector3 parentTranslationDiference = parentPosition - startParentPosition;
childPosition = rotatedVector + parentTranslationDiference;
}
``````

I would cheat. If you don’t want to use the “normal” parenting functions. I would parent an empty game object to the parent you want to use, then simply make the rotation and position the same from that object.

``````public Transform parent;
private Transform match;

void Start(){
match = new GameObject().transform;
match.position = transform.position;
match.rotation = transform.rotation;

if(parent) match.parent = parent;
}

void Update(){
if(parent){
transform.position = match.position;
transform.rotation = match.rotation;
}
}
``````

I can only assume that you are trying to avoid scaling issues with this.

I tried using temporary game objects before and it did work but I want to avoid doing that because of more clean code. Scaling is not an issue.

Um, why not just use the TRS matrix or the object you want to parent to?

Perhaps that would be possible to. Any idea how to implement that?

Edit:
On second thought, it will probably too slow constructing a TRS matrix because Unity doesn’t hold those internally. Perhaps it is better to use transforms after all…

This sounds interesting though, but it isn’t very clear how to implement this in Unity:
http://stackoverflow.com/questions/8594102/matrix-multiply-with-position-quaternion-and-scale-components

Edit2:
I settled with this for now. I am still interested in a pure math version if someone knows how to do that.

``````private static GameObject tempChild;
private static GameObject tempParent;

public static void Init(){

tempChild = new GameObject("TempChild");
tempParent = new GameObject("TempParent");

//set the parent
tempChild.transform.parent = tempParent.transform;
}

//This function translates one object as if it was parented to the other.
//Before using this function, the Init() function must be called
//Input: parentRotation and parentPosition: the current parent transform.
//Input: startParentRotation and startParentPosition: the transform of the parent object at the time the objects are parented.
//Input: startChildRotation and startChildPosition: the transform of the child object at the time the objects are parented.
//Output: childRotation and childPosition.
//All transforms are in world space.
public static void TransformWithParent(out Quaternion childRotation, out Vector3 childPosition, Quaternion parentRotation, Vector3 parentPosition, Quaternion startParentRotation, Vector3 startParentPosition, Quaternion startChildRotation, Vector3 startChildPosition){

childRotation = Quaternion.identity;
childPosition = Vector3.zero;

//set the parent start transform
tempParent.transform.rotation = startParentRotation;
tempParent.transform.position = startParentPosition;
tempParent.transform.localScale = Vector3.one; //to prevent scale wandering

//set the child start transform
tempChild.transform.rotation = startChildRotation;
tempChild.transform.position = startChildPosition;
tempChild.transform.localScale = Vector3.one; //to prevent scale wandering

//translate and rotate the child by moving the parent
tempParent.transform.rotation = parentRotation;
tempParent.transform.position = parentPosition;

//get the child transform
childRotation = tempChild.transform.rotation;
childPosition = tempChild.transform.position;
}
``````

Yeah it does…

http://docs.unity3d.com/Documentation/ScriptReference/Transform-worldToLocalMatrix.html

http://docs.unity3d.com/Documentation/ScriptReference/Transform-localToWorldMatrix.html

Also:

http://docs.unity3d.com/Documentation/ScriptReference/Matrix4x4.TRS.html

I got that info from here:

Maybe that information is out of date.

You may be right…

Off the top of my head (totally untested) this might (probably not) work…

``````public static void TransformWith(Transform parent, Transform child, Vector3 position, Quaternion rotation) {
float angle;
Vector3 axis;
child.position += position;
(parent.rotation * rotation).ToAngleAxis(out angle, out axis);
child.RotateAround(parent.position + position, axis, angle);
}
``````

It’s mostly the final rotation that’s the problem, rotateAround should be able to get you there but I doubt I have the correct axis and angle in the example above.

I’d probably not bother with this though and just parent/unparent as needed. Don’t worry about performance overhead unless you can measure it and say for certain that it’s going to be a problem. Pre-optimisation is the root of all evil!

``````public static void TransformWith(Transform parent, Transform child, Vector3 position, Quaternion rotation) {

Transform previousParent = child.parent;
Quaternion previousRotation = parent.rotation;
child.parent = parent;
parent.position += position;
parent.rotation *= rotation;
child.parent = previousParent;
parent.position -= position;
parent.rotation = previousRotation;

}
``````

Isn’t this just:

``````void SetTransformRelativeTo(Transform target, Transform parent, Vector3 localPosition, Quaternion localRotation)
{
target.position = parent.TransformPoint(localPosition);
target.rotation = parent.rotation * localRotation;
}
``````

I had big problems before by using Transform directly instead of using a GameObject so I tend to shy away from using Transforms without a GameObject.

Ahem… A Transform and a GameObject are both Components that exist on the same Object. You cannot have one without the other.

That’s what I eventually found out. So in any case, I don’t see the reason calling something Transform instead of gameObject.transform