extract_mid_level.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import argparse
  2. import sys
  3. import json
  4. import shutil
  5. from pathlib import Path
  6. # Add the utils directory to the Python path
  7. utils_path = Path(__file__).parent / 'utils'
  8. sys.path.append(str(utils_path))
  9. from file_utils import replicate_directory_structure, find_files_by_extension, create_guid_to_path_map
  10. from json_utils import write_json
  11. from scene_processor import UnitySceneProcessor
  12. def copy_scripts(assets_dir, output_assets_dir):
  13. """
  14. Copies all C# scripts (.cs) to the target directory.
  15. """
  16. print("\n--- Starting Script Handling ---")
  17. cs_files = find_files_by_extension(str(assets_dir), '.cs')
  18. print(f"Found {len(cs_files)} C# script files to copy.")
  19. for script_path_str in cs_files:
  20. script_path = Path(script_path_str)
  21. relative_path = script_path.relative_to(assets_dir)
  22. destination_path = output_assets_dir / relative_path
  23. destination_path.parent.mkdir(parents=True, exist_ok=True)
  24. try:
  25. shutil.copy(script_path, destination_path)
  26. except IOError as e:
  27. print(f"Error copying {script_path} to {destination_path}: {e}", file=sys.stderr)
  28. print("Script copying complete.")
  29. def main():
  30. """
  31. Main function to run the mid-level data extraction process.
  32. This script orchestrates the parsing of scene and prefab files.
  33. """
  34. parser = argparse.ArgumentParser(
  35. description="Generates a virtual representation of the project's structure."
  36. )
  37. parser.add_argument(
  38. "--input",
  39. type=str,
  40. required=True,
  41. help="The root directory of the target Unity project."
  42. )
  43. parser.add_argument(
  44. "--output",
  45. type=str,
  46. required=True,
  47. help="The directory where the generated output folder will be saved."
  48. )
  49. parser.add_argument(
  50. "--indent",
  51. type=int,
  52. default=None,
  53. help="Indentation level for JSON output. Defaults to None (compact)."
  54. )
  55. args = parser.parse_args()
  56. input_dir = Path(args.input).resolve()
  57. output_dir = Path(args.output).resolve()
  58. if not input_dir.is_dir():
  59. print(f"Error: Input path '{input_dir}' is not a valid directory.", file=sys.stderr)
  60. sys.exit(1)
  61. # --- Setup Output Directories ---
  62. mid_level_output_dir = output_dir / "MidLevel"
  63. output_assets_dir = mid_level_output_dir / "Assets"
  64. try:
  65. output_assets_dir.mkdir(parents=True, exist_ok=True)
  66. print(f"Output will be saved to: {mid_level_output_dir}")
  67. except OSError as e:
  68. print(f"Error: Could not create output directory '{mid_level_output_dir}'. {e}", file=sys.stderr)
  69. sys.exit(1)
  70. assets_dir = input_dir / "Assets"
  71. if not assets_dir.is_dir():
  72. print(f"Warning: 'Assets' directory not found in '{input_dir}'. Skipping all processing.", file=sys.stderr)
  73. return
  74. # --- Task 1: Replicate 'Assets' directory structure ---
  75. print(f"\n--- Replicating 'Assets' directory structure ---")
  76. replicate_directory_structure(str(assets_dir), str(output_assets_dir))
  77. print("Directory structure replication complete.")
  78. # --- Task 2: Copy C# Scripts ---
  79. copy_scripts(assets_dir, output_assets_dir)
  80. # --- Task 3: Generate GUID Map ---
  81. print("\n--- Generating GUID Map ---")
  82. guid_map = create_guid_to_path_map(str(input_dir))
  83. guid_map_path = mid_level_output_dir / "guid_map.json"
  84. try:
  85. # Use the new centralized utility
  86. write_json(guid_map, guid_map_path, indent=args.indent)
  87. print(f"Successfully created GUID map: {guid_map_path}")
  88. except Exception as e:
  89. print(f"Error writing GUID map: {e}", file=sys.stderr)
  90. sys.exit(1)
  91. # --- Task 4: Orchestrate Scene and Prefab Parsing ---
  92. print("\n--- Starting Scene/Prefab Parsing Orchestration ---")
  93. scene_files = find_files_by_extension(str(assets_dir), '.unity')
  94. prefab_files = find_files_by_extension(str(assets_dir), '.prefab')
  95. files_to_process = scene_files + prefab_files
  96. print(f"Found {len(files_to_process)} scene/prefab files to process.")
  97. # Create a single processor instance to use for all files
  98. processor = UnitySceneProcessor(guid_map)
  99. for file_path_str in files_to_process:
  100. file_path = Path(file_path_str)
  101. relative_path = file_path.relative_to(assets_dir)
  102. output_path = output_assets_dir / relative_path
  103. output_path = output_path.with_suffix('.json')
  104. try:
  105. print(f"\n--- Processing: {file_path.name} ---")
  106. # Process the file and get the result
  107. result = processor.process_file(file_path)
  108. # Ensure the output directory exists
  109. output_path.parent.mkdir(parents=True, exist_ok=True)
  110. # Write the result using the centralized utility
  111. write_json(result, output_path, indent=args.indent)
  112. print(f"Successfully processed {file_path.name} -> {output_path}")
  113. except Exception as e:
  114. print(f"Error processing {file_path.name}: {e}", file=sys.stderr)
  115. # Potentially continue to the next file
  116. # sys.exit(1)
  117. print("\nMid-level extraction complete.")
  118. if __name__ == "__main__":
  119. main()