
Use case 1:
Link between gameobjects in scene

--- !u!1 &330585543
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 330585546} -> Usually the first one is transform
- component: {fileID: 330585545} -> Any component that is not transform
- component: {fileID: 330585544} -> Any component that is not transform
- component: {fileID: 330585547} -> Any component that is not transform
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1

Transform data:

--- !u!4 &330585546
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 330585543}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 1429936258} -> This refers to the first child's transform
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

--- !u!4 &1429936258
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1429936256} -> This refers to the transform's gameobject data reference
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.2898221, y: -23.73114, z: -48.733814}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 330585546}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

--- !u!1 &1429936256
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1429936258} 
- component: {fileID: 1429936257}
- component: {fileID: 1429936259}
m_Layer: 0
m_Name: MEEE
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1

Now, we have a link between the gameobject and the transform and their children. So for game object the children link are found using the transform data.
So the way to traverse is: GameObject -> Transform -> Children -> <For Each Child> -> Transform -> GameObject, now we append the gameobject1 child info with the gameobject2. This is the way to traverse the hierarchy to find the parent-child relationship between scene objects.


Use case 2:

Prefab in root, with no children & no overrides:

--- !u!1001 &1482527665
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
    m_TransformParent: {fileID: 0}
    m_Modifications:
    m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 61c90d4029cba460eaac555f5cfa2f97, type: 3}


There are no additional artifacts that unity generates, so in this use case, since the 'm_TransformParent' is 0, the prefab is in the root of the scene, with no custom scene objects as children + no overrides.


Use case 3:

Prefab in root with overrides:

--- !u!1001 &1482527665
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_SourcePrefab: {fileID: 100100000, guid: 61c90d4029cba460eaac555f5cfa2f97, type: 3}
--- !u!1 &1482527666 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 5118133154516674719, guid: 61c90d4029cba460eaac555f5cfa2f97,
type: 3}
m_PrefabInstance: {fileID: 1482527665}
m_PrefabAsset: {fileID: 0}
--- !u!65 &1482527667
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1482527666}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}

Here in this use case, prefab has a override of a box collider, in that case unity would generate a ghost gameobject with prefab instance reference, where the box collider would have reference of gameobject.
The way to note this is to identify if the gameobject data is stripped, then ideally just assume that the gameobject is a ghost created for prefab. It wouldn't have components list of identify the components that are attached on this prefab.
So, we iterate through components which have m_GameObject and identify gameobject, and then implicitly see if the gameobject is stripped, then we identify its prefab instance.

Use case 4:

Prefab with a scene object as child:

--- !u!1001 &1482527665
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 61c90d4029cba460eaac555f5cfa2f97, type: 3}
--- !u!4 &1482527666 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 7908724477659422290, guid: 61c90d4029cba460eaac555f5cfa2f97,
type: 3}
m_PrefabInstance: {fileID: 1482527665}
m_PrefabAsset: {fileID: 0}
--- !u!1 &309364077
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 309364078}
- component: {fileID: 309364081}
- component: {fileID: 309364080}
- component: {fileID: 309364079}
  m_Layer: 0
  m_Name: Cube
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &309364078
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 309364077}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 1
m_Children: []
m_Father: {fileID: 1482527666}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

Here, the prefab has a child which is a scene object called cube. Here note, a ghost transform is generated against the prefab. The way the link works is the Cube (GameObject) -> Cube (Transform) ->  Check m_Father property -> Find related transform -> See if the transform property is stripped -> If stripped, then it is a ghost.
Since we identified it is a ghost, we find the transform's 'm_PrefabInstance' and identify what is the prefab instance that this transform is related to. Now due to this, we can identify that this is a prefab with a scene object (Cube) as child.

Use case 5:

Prefab with a prefab as child:

--- !u!1001 &1482527665
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 61c90d4029cba460eaac555f5cfa2f97, type: 3}
--- !u!4 &1482527666 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 7908724477659422290, guid: 61c90d4029cba460eaac555f5cfa2f97, type: 3}
m_PrefabInstance: {fileID: 1482527665}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &617805067
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 1482527666}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 7cf72a57738ed4c1e993c0388fa836d4, type: 3}

Here one prefab instance has reference of another prefab instance. Here, the way we identify the relationship is by finding the 'm_TransformParent' property. If it is not 0, then it means the prefab has a parent.
If we check the parent, which is linked to a stripped transform, we know that the transform is related to a prefab. We can then find the prefab instance. This is the way to traverse the prefab hierarchy.


Use case 6:

Prefab with scene object as parent:

--- !u!1001 &1482527665
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 491276561}
m_Modifications:
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 61c90d4029cba460eaac555f5cfa2f97, type: 3}
--- !u!4 &1482527666 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 7908724477659422290, guid: 61c90d4029cba460eaac555f5cfa2f97,
type: 3}
m_PrefabInstance: {fileID: 1482527665}
m_PrefabAsset: {fileID: 0}
--- !u!1 &491276560
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 491276561}
  m_Layer: 0
  m_Name: Sala
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
  --- !u!4 &491276561
  Transform:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 491276560}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 0, z: 0}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_ConstrainProportionsScale: 1
  m_Children:
- {fileID: 1482527666}
  m_Father: {fileID: 0}
  m_RootOrder: 3
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

Here while parsing through gameobject, if we identify, the trasform has a child, and that child's transform is stripped, that means, the transform is related to a prefab. We can then find the prefab instance. This is the way to traverse the prefab hierarchy. 


Use case 7:

Prefab with the scene object as child for one of the prefab's children:

--- !u!1 &5604345
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5604346}
  m_Layer: 0
  m_Name: PEACE
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
  --- !u!4 &5604346
  Transform:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 5604345}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 0, z: 0}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_ConstrainProportionsScale: 1
  m_Children: []
  m_Father: {fileID: 920412709}
  m_RootOrder: 0
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
  --- !u!1001 &920412706
  PrefabInstance:
  m_ObjectHideFlags: 0
  serializedVersion: 2
  m_Modification:
  m_TransformParent: {fileID: 0}
  m_Modifications:
  m_RemovedComponents: []
  m_SourcePrefab: {fileID: 100100000, guid: 874028b39d9764ee997aa13686619919, type: 3}
  --- !u!4 &920412709 stripped
  Transform:
  m_CorrespondingSourceObject: {fileID: 8145956705230478064, guid: 874028b39d9764ee997aa13686619919,
  type: 3}
  m_PrefabInstance: {fileID: 920412706}
  m_PrefabAsset: {fileID: 0}

To identify the parent child relationship, where the father of a scene object is prefab and that object can be 'n'th child of the prefab, we use the following steps:

Step 1: Find "PEACE" and its Parent in SampleScene.unity

First, we locate the "PEACE" GameObject in the scene file to find its direct parent.

1. We search for m_Name: PEACE. This leads us to the GameObject with ID &5604345.
2. This GameObject has one component, a Transform with fileID: 5604346.
3. We examine the Transform component with ID &5604346:

--- !u!4 &5604346
 Transform:
   # ...
   m_GameObject: {fileID: 5604345}
   m_Father: {fileID: 920412709}
   m_RootOrder: 0
     - Parent ID: The m_Father is 920412709.
     - Sibling Index: The m_RootOrder is 0.

This gives us the last number in our sequence: (?-?-0).

Step 2: Identify the Parent (920412709) in SampleScene.unity

Now, we look for the object with ID 920412709 in the scene file.

--- !u!4 &920412709 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 8145956705230478064, guid: 874028b39d9764ee997aa13686619919, type: 3}
m_PrefabInstance: {fileID: 920412706}
m_PrefabAsset: {fileID: 0}

- The stripped keyword tells us this Transform is part of a prefab instance. Its properties are not defined here.
- To find its real properties (like its parent and name), we must look inside the source prefab.
- The m_CorrespondingSourceObject gives us the fileID of the original Transform inside the prefab file: 8145956705230478064.

Step 3: Find the Corresponding Transform in Parent.prefab

We now switch to the Parent.prefab file and search for the Transform with ID &8145956705230478064.

1. Locating &8145956705230478064:

--- !u!4 &8145956705230478064
Transform:
  # ...
  m_GameObject: {fileID: 1790231484505338027}
  m_Father: {fileID: 1455291841571425918}
  m_RootOrder: 0

2. We can now identify this object and its parent:
  - Its m_GameObject is 1790231484505338027. Looking up this GameObject reveals its name: m_Name: SpawnPoint. So, 920412709 in the scene is the "SpawnPoint" Transform.
  - Parent ID: The m_Father is 1455291841571425918.
  - Sibling Index: The m_RootOrder is 0.

This gives us the second number in our sequence: (?-0-0).

Step 4: Find the Next Parent (1455291841571425918) in Parent.prefab

We continue up the hierarchy within the prefab file, looking for the Transform with ID &1455291841571425918.

1. Locating &1455291841571425918:

--- !u!4 &1455291841571425918
Transform:
  # ...
  m_GameObject: {fileID: 8435291834557686729}
  m_Father: {fileID: 6729460392160249717}
  m_RootOrder: 0

2. We identify this object and its parent:
  - Its m_GameObject is 8435291834557686729. Looking up this GameObject reveals its name: m_Name: Launcher.
  - Parent ID: The m_Father is 6729460392160249717.
  - Sibling Index: The m_RootOrder is 0.

This gives us the first number in our sequence: (0-0-0).

Final Verification: The Prefab Root

To be certain, we can check the final parent, Transform &6729460392160249717.

--- !u!4 &6729460392160249717
Transform:
# ...
m_GameObject: {fileID: 5669290172027642543}
m_Father: {fileID: 0}
m_RootOrder: 0

Its m_Father is {fileID: 0}, which signifies that it is the root Transform of the prefab, as it has no parent. Its GameObject (5669290172027642543) is named "Parent".

By parsing the files and following the m_Father and m_RootOrder references, we have programmatically confirmed that the deep sibling index of the "PEACE" GameObject is indeed (0-0-0).


Conclusion:

So essentially, it is beneficial to resolve the parent-child relationship between normal game objects in the scene using m_Parent logic.
Whenever, we deal with a prefab instance, we create a relationship of child-parent between the prefab instance and it's found normal scene object parent. The transforms can be stripped out of the prefab instances in the final output, since the relationship is already resolved.
In instances where a scene object has a prefab as a parent, we add the deep sibling index json property, which exactly tells where does the scene object exist in the prefab hierarchy within scene.
So irrespective of which sibling index's child the scene object is, we add it always to the root of the prefab data object and add children with the deep sibling index data.
Finally, one more pass of run through in the left over data, to see if any gameobject is missed out, then they are marked as orphans and exported.
Now, since this is done, we append the components name to the component section of every gameobject that has been identified and created a virtual tree out of.
Ultimately, we parse through our collated data, and find the m_RootObjects in the root objects found and sort the objects in root based on them.
Note: When extracting information from prefab's modification, check if it has value of 'm_IsActive' in 'm_Modifications' inside m_Modification object of PrefabInstance, we need only this value and 'm_RemovedComponents' property to be exported from the prefab instance.