12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import sys
- from pathlib import Path
- import ruamel.yaml
- # Add the utils directory to the Python path
- utils_path = Path(__file__).parent
- sys.path.append(str(utils_path))
- from yaml_utils import load_unity_yaml, convert_to_plain_python_types
- def build_virtual_tree(file_path, object_map, guid_map):
- """
- Parses a Unity scene/prefab's data to build a nested dictionary
- representing the GameObject hierarchy with resolved component names and correct children.
- """
- nodes = {}
- transform_to_gameobject = {}
- child_to_parent_transform = {}
- # --- Pass 1: Create all nodes and map all relationships ---
- for file_id, obj_data in object_map.items():
- if 'GameObject' in obj_data:
- go_info = obj_data['GameObject']
-
- resolved_components = []
- for comp_ref in go_info.get('m_Component', []):
- comp_id = str(comp_ref['component']['fileID'])
- if comp_id not in object_map:
- continue
- comp_data = object_map[comp_id]
- if 'MonoBehaviour' in comp_data:
- script_guid = comp_data['MonoBehaviour'].get('m_Script', {}).get('guid')
- if script_guid:
- resolved_components.append({"script": {"guid": script_guid}})
- else:
- comp_name = next((key for key in comp_data if key != 'm_ObjectHideFlags'), None)
- if comp_name:
- resolved_components.append(comp_name)
- nodes[file_id] = {
- 'fileID': file_id,
- 'm_Name': go_info.get('m_Name'),
- 'm_IsActive': go_info.get('m_IsActive', 1),
- 'm_TagString': go_info.get('m_TagString'),
- 'm_Layer': go_info.get('m_Layer'),
- 'm_Components': resolved_components,
- 'm_Children': []
- }
-
- elif 'Transform' in obj_data:
- # Map the parent-child relationship between transforms
- father_id = str(obj_data['Transform'].get('m_Father', {}).get('fileID', '0'))
- if father_id != '0':
- child_to_parent_transform[file_id] = father_id
-
- # Map the transform back to its owning GameObject
- gameobject_id = str(obj_data['Transform'].get('m_GameObject', {}).get('fileID', '0'))
- if gameobject_id != '0':
- transform_to_gameobject[file_id] = gameobject_id
- # --- Pass 2: Build the hierarchy ---
- root_nodes = []
- for transform_id, gameobject_id in transform_to_gameobject.items():
- if gameobject_id in nodes:
- parent_transform_id = child_to_parent_transform.get(transform_id)
- if parent_transform_id and parent_transform_id in transform_to_gameobject:
- parent_gameobject_id = transform_to_gameobject[parent_transform_id]
- if parent_gameobject_id in nodes:
- # This is a child, append it to its parent
- nodes[parent_gameobject_id]['m_Children'].append(nodes[gameobject_id])
- else:
- # This is a root GameObject
- root_nodes.append(nodes[gameobject_id])
- return root_nodes
|