parse_scenes_and_prefabs.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import argparse
  2. import sys
  3. import json
  4. from pathlib import Path
  5. # Add the utils directory to the Python path
  6. utils_path = Path(__file__).parent.parent / 'utils'
  7. sys.path.append(str(utils_path))
  8. from file_utils import find_files_by_extension
  9. from deep_parser import parse_scene_or_prefab
  10. from json_utils import write_json
  11. from yaml_utils import load_unity_yaml, convert_to_plain_python_types
  12. from hierarchy_utils import HierarchyParser
  13. def main():
  14. parser = argparse.ArgumentParser(description="Parses scenes and prefabs into a per-GameObject breakdown.")
  15. parser.add_argument("--input", type=str, required=True, help="The root directory of the target Unity project.")
  16. parser.add_argument("--output", type=str, required=True, help="The directory where the output will be saved.")
  17. parser.add_argument("--indent", type=int, default=None)
  18. parser.add_argument("--shrink-json", action='store_true')
  19. parser.add_argument("--ignored-folders", type=str, default='[]', help='JSON string of folders to ignore.')
  20. args = parser.parse_args()
  21. try:
  22. ignored_folders = json.loads(args.ignored_folders)
  23. except json.JSONDecodeError:
  24. print("Warning: Could not parse ignored-folders JSON string. Defaulting to empty list.", file=sys.stderr)
  25. ignored_folders = []
  26. input_dir = Path(args.input).resolve()
  27. output_dir = Path(args.output).resolve()
  28. assets_dir = input_dir / "Assets"
  29. if not assets_dir.is_dir():
  30. return
  31. scene_files = find_files_by_extension(str(assets_dir), '.unity', ignored_folders=ignored_folders, project_root=input_dir)
  32. prefab_files = find_files_by_extension(str(assets_dir), '.prefab', ignored_folders=ignored_folders, project_root=input_dir)
  33. files_to_process = scene_files + prefab_files
  34. if not files_to_process:
  35. print("No scene or prefab files found.")
  36. return
  37. print(f"\n--- Starting Scene/Prefab Parsing ---")
  38. print(f"Found {len(files_to_process)} files to process.")
  39. total_files = len(files_to_process)
  40. for i, file_path_str in enumerate(files_to_process):
  41. file_path = Path(file_path_str)
  42. print(f"\n--- Processing file {i+1}/{total_files}: {file_path.relative_to(input_dir)} ---")
  43. # --- Step 1: Deep Parsing ---
  44. print(" [1/2] Starting deep parse to extract all GameObjects...")
  45. gameobject_list = parse_scene_or_prefab(str(file_path))
  46. relative_path = file_path.relative_to(input_dir)
  47. asset_output_dir = output_dir / relative_path
  48. asset_output_dir.mkdir(parents=True, exist_ok=True)
  49. if gameobject_list:
  50. print(f" -> Deep parse complete. Found {len(gameobject_list)} GameObjects.")
  51. print(f" -> Saving individual GameObject files to {asset_output_dir}...")
  52. for go_data in gameobject_list:
  53. file_id = go_data.get('fileID')
  54. if file_id:
  55. output_json_path = asset_output_dir / f"{file_id}.json"
  56. write_json(go_data, output_json_path, indent=args.indent, shrink=args.shrink_json)
  57. print(f" -> Finished saving GameObject files.")
  58. else:
  59. print(f" -> Skipped deep parsing for {file_path.name} (no objects found or file was empty).")
  60. # --- Step 2: Hierarchy Parsing ---
  61. print(" [2/2] Starting hierarchy parse to identify root objects...")
  62. try:
  63. documents = load_unity_yaml(file_path)
  64. if not documents:
  65. print(" -> Skipping hierarchy parse (file is empty or could not be read).")
  66. continue
  67. print(" -> Converting YAML for hierarchy analysis...")
  68. raw_object_map = {int(doc.anchor.value): doc for doc in documents if hasattr(doc, 'anchor') and doc.anchor is not None}
  69. object_map = {file_id: convert_to_plain_python_types(obj) for file_id, obj in raw_object_map.items()}
  70. print(" -> Analyzing transform hierarchy to find roots...")
  71. parser = HierarchyParser(object_map)
  72. root_object_ids = parser.get_root_object_ids()
  73. root_ids_list = [file_id for file_id, _ in root_object_ids]
  74. if root_ids_list:
  75. roots_output_path = asset_output_dir / "root_objects.json"
  76. write_json(root_ids_list, roots_output_path, indent=args.indent, shrink=args.shrink_json)
  77. print(f" -> Successfully saved {len(root_ids_list)} root object IDs to {roots_output_path}")
  78. else:
  79. print(" -> No root objects found.")
  80. except Exception as e:
  81. print(f" -> Error during hierarchy parsing for {file_path.name}: {e}", file=sys.stderr)
  82. print("\nScene and prefab parsing complete.")
  83. if __name__ == "__main__":
  84. main()