Understanding root vs parent

I have a scene with one object called ParentRoot. It has one child called GameManager. The GameManager has a script. In that script’s Start I call the following code:

	Debug.Log("transform 1" + transform.root.root);     // transform 1ParentRoot (UnityEngine.Transform)
	Debug.Log("transform 2" + transform.root.parent);   // transform 2
	Debug.Log("transform 3" + transform.parent.root);   // transform 3ParentRoot (UnityEngine.Transform)
	Debug.Log("transform 4" + transform.parent.parent); // transform 4

Can anyone explain the behaviour to me please?

Why does parent.parent in scenario 4 not work? The scripts’ parent is GameManager (as can be deduced to work from scenario 3) but why does the ParentRoot which the GameManager is nested under not count as it’s parent?

Why does root.root work in scenario 1. It’s strange that you can access the script’s GameManager parent via both the parent and root accessors.

What’s the correct way of thinking about what parent vs root gives you please?

Transform.root

Returns the topmost transform in the hierarchy.

(This never returns null, if this Transform doesn’t have a parent it returns itself.)

transform.root.root will return ParentRoot (so does transform.root since ParentRoot is already the root, so asking the root of the root returns the root itself)

transform.root.parent will necessarily return null because the root is the top most transform in the hierarchy (i.e the transform without parent)

transform.parent.root will return the root object of the parent object (the parent is ParentRoot here), so the root of ParentRoot is ParentRoot itself (because ParentRoot is the root)

transform.parent.parent returns null because transform.parent = ParentRoot, which does not have any parent.