convert_scene.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import yaml
  2. import json
  3. import re
  4. import sys
  5. import argparse
  6. import os
  7. # Regex to capture the type ID and anchor ID from the document separator
  8. header_pattern = re.compile(r"--- !u!(\d+) &(\S+)")
  9. # Regex to find and remove the tags for the parser
  10. tag_remover_pattern = re.compile(r"!u!\d+\s")
  11. def convert_unity_yaml_to_json(yaml_content):
  12. """
  13. Parses a Unity YAML file string, preserving fileID references, and returns a JSON string.
  14. """
  15. json_data = []
  16. # First, find all the original headers
  17. headers = header_pattern.findall(yaml_content)
  18. # Next, remove the problematic tags from the content so the parser doesn't fail
  19. sanitized_content = tag_remover_pattern.sub("", yaml_content)
  20. # Use the standard SafeLoader, as the tags are now gone
  21. documents = list(yaml.safe_load_all(sanitized_content))
  22. # The first document is the file info, which we can often skip if it's empty
  23. if documents and isinstance(documents[0], str) and 'YAML' in documents[0]:
  24. documents.pop(0)
  25. if len(headers) != len(documents):
  26. print(f"Warning: Mismatch between headers found ({len(headers)}) and documents parsed ({len(documents)}).", file=sys.stderr)
  27. for i, doc in enumerate(documents):
  28. if i < len(headers):
  29. type_id, anchor_id = headers[i]
  30. structured_doc = {
  31. 'type_id': type_id,
  32. 'anchor_id': anchor_id,
  33. 'data': doc
  34. }
  35. json_data.append(structured_doc)
  36. else:
  37. # Append any extra docs without headers (should be rare in Unity files)
  38. json_data.append({'data': doc})
  39. # Use compact encoding for the final JSON
  40. return json.dumps(json_data)
  41. def main():
  42. parser = argparse.ArgumentParser(description='Convert Unity YAML assets to JSON.')
  43. parser.add_argument('input_path', type=str, help='Absolute path to the input Unity asset file.')
  44. parser.add_argument('output_path', type=str, help='Absolute path for the output JSON file.')
  45. args = parser.parse_args()
  46. input_path = args.input_path
  47. output_path = args.output_path
  48. try:
  49. # Ensure the output directory exists
  50. output_dir = os.path.dirname(output_path)
  51. if not os.path.exists(output_dir):
  52. os.makedirs(output_dir)
  53. with open(input_path, 'r') as f:
  54. content = f.read()
  55. json_output = convert_unity_yaml_to_json(content)
  56. with open(output_path, 'w') as f:
  57. f.write(json_output)
  58. print(f"Successfully converted '{input_path}' to '{output_path}'")
  59. except Exception as e:
  60. print(f"An error occurred: {e}", file=sys.stderr)
  61. sys.exit(1)
  62. if __name__ == "__main__":
  63. main()