| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 | 
							- from pathlib import Path
 
- class HierarchyParser:
 
-     """
 
-     Parses a Unity scene's object_map to identify parent-child relationships
 
-     and determine the root objects in the hierarchy.
 
-     """
 
-     def __init__(self, object_map):
 
-         self.object_map = object_map
 
-         self.transform_to_gameobject = {}
 
-         self.gameobject_to_transform = {}
 
-         self.transform_children = {}
 
-         self.prefab_instances = {}
 
-         self.stripped_transforms = {}
 
-         self.all_child_ids = set()
 
-         self._build_maps()
 
-         self._find_all_children()
 
-     def _build_maps(self):
 
-         """
 
-         First pass over the object map to build essential lookups for transforms,
 
-         GameObjects, and PrefabInstances.
 
-         """
 
-         for file_id, obj_data in self.object_map.items():
 
-             if 'Transform' in obj_data:
 
-                 transform_info = obj_data['Transform']
 
-                 gameobject_id = transform_info.get('m_GameObject', {}).get('fileID')
 
-                 if gameobject_id:
 
-                     self.transform_to_gameobject[file_id] = gameobject_id
 
-                     self.gameobject_to_transform[gameobject_id] = file_id
 
-                 
 
-                 parent_id = transform_info.get('m_Father', {}).get('fileID')
 
-                 if parent_id and parent_id != 0:
 
-                     if parent_id not in self.transform_children:
 
-                         self.transform_children[parent_id] = []
 
-                     self.transform_children[parent_id].append(file_id)
 
-                 prefab_instance_id = transform_info.get('m_PrefabInstance', {}).get('fileID')
 
-                 if prefab_instance_id:
 
-                     self.stripped_transforms[file_id] = prefab_instance_id
 
-             elif 'PrefabInstance' in obj_data:
 
-                 prefab_info = obj_data['PrefabInstance']
 
-                 modifications = prefab_info.get('m_Modification', {})
 
-                 parent_id = modifications.get('m_TransformParent', {}).get('fileID')
 
-                 if parent_id and parent_id != 0:
 
-                     self.prefab_instances[file_id] = {'parent': parent_id}
 
-     def _find_all_children(self):
 
-         """
 
-         Iterates through the built maps to populate a set of all fileIDs that
 
-         are children of another object.
 
-         """
 
-         # Children of regular GameObjects (via Transform)
 
-         for parent_id, children in self.transform_children.items():
 
-             for child_transform_id in children:
 
-                 child_go_id = self.transform_to_gameobject.get(child_transform_id)
 
-                 if child_go_id:
 
-                     self.all_child_ids.add(child_go_id)
 
-                 # Also add stripped transforms that point to prefabs
 
-                 elif child_transform_id in self.stripped_transforms:
 
-                     prefab_instance_id = self.stripped_transforms[child_transform_id]
 
-                     self.all_child_ids.add(prefab_instance_id)
 
-         # Children that are PrefabInstances
 
-         for prefab_id, prefab_data in self.prefab_instances.items():
 
-             self.all_child_ids.add(prefab_id)
 
-     def get_root_object_ids(self):
 
-         """
 
-         Identifies all root objects (GameObjects and PrefabInstances) and returns
 
-         them as a sorted list of tuples containing (fileID, m_RootOrder).
 
-         """
 
-         root_objects = []
 
-         # Find root GameObjects
 
-         for go_id, transform_id in self.gameobject_to_transform.items():
 
-             if go_id not in self.all_child_ids:
 
-                 transform_info = self.object_map.get(transform_id, {}).get('Transform', {})
 
-                 root_order = transform_info.get('m_RootOrder', 999999)
 
-                 root_objects.append((go_id, root_order))
 
-         # Find root PrefabInstances
 
-         for prefab_id, obj_data in self.object_map.items():
 
-             if 'PrefabInstance' not in obj_data:
 
-                 continue
 
-             
 
-             if prefab_id not in self.all_child_ids:
 
-                 modifications = obj_data['PrefabInstance'].get('m_Modification', {})
 
-                 root_order = 999999
 
-                 for mod in modifications.get('m_Modifications', []):
 
-                     if mod.get('propertyPath') == 'm_RootOrder':
 
-                         root_order = mod.get('value', 999999)
 
-                         break
 
-                 root_objects.append((prefab_id, root_order))
 
-         
 
-         # Sort all root objects by their m_RootOrder
 
-         root_objects.sort(key=lambda x: x[1])
 
-         
 
-         return root_objects
 
 
  |