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.

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…

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;
}

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!