import argparse import sys import json import shutil from pathlib import Path # Add the utils directory to the Python path utils_path = Path(__file__).parent / 'utils' sys.path.append(str(utils_path)) from file_utils import replicate_directory_structure, find_files_by_extension, create_guid_to_path_map from json_utils import write_json from scene_processor import UnitySceneProcessor def generate_guid_mappers(input_dir, output_dir, indent=None): """ Finds all .meta files and generates JSON files mapping GUIDs to asset paths. """ print("\n--- Starting GUID Mapper Generation ---") assets_dir = input_dir / "Assets" if not assets_dir.is_dir(): print(f"Error: 'Assets' directory not found in '{input_dir}'", file=sys.stderr) return meta_files = find_files_by_extension(str(assets_dir), '.meta') print(f"Found {len(meta_files)} .meta files to process.") asset_type_map = { '.prefab': 'prefabs', '.unity': 'scenes', '.mat': 'materials', '.cs': 'scripts', '.png': 'textures', '.jpg': 'textures', '.jpeg': 'textures', '.asset': 'scriptable_objects', } guid_maps = {value: {} for value in asset_type_map.values()} guid_maps['others'] = {} for meta_file_path_str in meta_files: meta_file_path = Path(meta_file_path_str) asset_file_path = Path(meta_file_path_str.rsplit('.meta', 1)[0]) if not asset_file_path.is_file(): continue guid = None try: with open(meta_file_path, 'r', encoding='utf-8') as f: for line in f: if line.strip().startswith('guid:'): guid = line.strip().split(':')[1].strip() break except Exception as e: print(f"Warning: Could not read or parse guid from {meta_file_path}. {e}", file=sys.stderr) continue if guid: asset_ext = asset_file_path.suffix.lower() asset_type = asset_type_map.get(asset_ext, 'others') relative_path = asset_file_path.relative_to(input_dir).as_posix() guid_maps[asset_type][guid] = relative_path mappers_dir = output_dir / "GuidMappers" try: mappers_dir.mkdir(parents=True, exist_ok=True) for asset_type, guid_map in guid_maps.items(): if guid_map: output_path = mappers_dir / f"{asset_type}.json" write_json(guid_map, output_path, indent=indent) print(f"Successfully created GUID mappers in {mappers_dir}") except OSError as e: print(f"Error: Could not create GUID mapper directory or files. {e}", file=sys.stderr) def main(): """ Main function to run the mid-level data extraction process. This script orchestrates the parsing of scene and prefab files. """ parser = argparse.ArgumentParser( description="Generates a virtual representation of the project's structure." ) parser.add_argument( "--input", type=str, required=True, help="The root directory of the target Unity project." ) parser.add_argument( "--output", type=str, required=True, help="The directory where the generated output folder will be saved." ) parser.add_argument( "--indent", type=int, default=None, help="Indentation level for JSON output. Defaults to None (compact)." ) args = parser.parse_args() input_dir = Path(args.input).resolve() output_dir = Path(args.output).resolve() if not input_dir.is_dir(): print(f"Error: Input path '{input_dir}' is not a valid directory.", file=sys.stderr) sys.exit(1) # --- Setup Output Directories --- mid_level_output_dir = output_dir / "MidLevel" output_assets_dir = mid_level_output_dir / "Assets" try: output_assets_dir.mkdir(parents=True, exist_ok=True) print(f"Output will be saved to: {mid_level_output_dir}") except OSError as e: print(f"Error: Could not create output directory '{mid_level_output_dir}'. {e}", file=sys.stderr) sys.exit(1) assets_dir = input_dir / "Assets" if not assets_dir.is_dir(): print(f"Warning: 'Assets' directory not found in '{input_dir}'. Skipping all processing.", file=sys.stderr) return # --- Task 1: Replicate 'Assets' directory structure --- print(f"\n--- Replicating 'Assets' directory structure ---") replicate_directory_structure(str(assets_dir), str(output_assets_dir)) print("Directory structure replication complete.") # --- Task 2: Generate GUID Map --- print("\n--- Generating GUID Map ---") guid_map = create_guid_to_path_map(str(input_dir)) guid_map_path = mid_level_output_dir / "guid_map.json" try: # Use the new centralized utility write_json(guid_map, guid_map_path, indent=args.indent) print(f"Successfully created GUID map: {guid_map_path}") except Exception as e: print(f"Error writing GUID map: {e}", file=sys.stderr) sys.exit(1) # --- Task 3: Generate Detailed GUID Mappers --- generate_guid_mappers(input_dir, mid_level_output_dir, indent=args.indent) # --- Task 4: Orchestrate Scene and Prefab Parsing --- print("\n--- Starting Scene/Prefab Parsing Orchestration ---") scene_files = find_files_by_extension(str(assets_dir), '.unity') prefab_files = find_files_by_extension(str(assets_dir), '.prefab') files_to_process = scene_files + prefab_files print(f"Found {len(files_to_process)} scene/prefab files to process.") # Create a single processor instance to use for all files processor = UnitySceneProcessor(guid_map) for file_path_str in files_to_process: file_path = Path(file_path_str) relative_path = file_path.relative_to(assets_dir) output_path = output_assets_dir / relative_path output_path = output_path.with_suffix('.json') try: print(f"\n--- Processing: {file_path.name} ---") # Process the file and get the result result = processor.process_file(file_path) # Ensure the output directory exists output_path.parent.mkdir(parents=True, exist_ok=True) # Write the result using the centralized utility write_json(result, output_path, indent=args.indent) print(f"Successfully processed {file_path.name} -> {output_path}") except Exception as e: print(f"Error processing {file_path.name}: {e}", file=sys.stderr) # Potentially continue to the next file # sys.exit(1) print("\nMid-level extraction complete.") if __name__ == "__main__": main()