ComponentDataProvider.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using System;
  2. using UnityEditor;
  3. using UnityEngine;
  4. using System.Collections.Generic;
  5. using Object = UnityEngine.Object;
  6. namespace LLM.Editor.Analysis
  7. {
  8. /// <summary>
  9. /// Provides detailed, serialized data for a specific component on a GameObject.
  10. /// </summary>
  11. public class ComponentDataProvider : IContextProvider
  12. {
  13. public object GetContext(Object target, string qualifier)
  14. {
  15. if (target is not GameObject go)
  16. {
  17. return "Error: Target must be a GameObject to get component data.";
  18. }
  19. if (string.IsNullOrEmpty(qualifier))
  20. {
  21. return "Error: Component type name (qualifier) is required.";
  22. }
  23. var componentType = GetTypeByName(qualifier);
  24. if (componentType == null)
  25. {
  26. return $"Error: Component type '{qualifier}' not found.";
  27. }
  28. Component component;
  29. try
  30. {
  31. component = go.GetComponent(componentType);
  32. }
  33. catch (Exception exception)
  34. {
  35. return $"Error: Failed to get component '{qualifier}': {exception.Message}";
  36. }
  37. return !component ? $"Error: Component '{qualifier}' not found on GameObject '{go.name}'." :
  38. // Reuse the generic serialization logic for any component.
  39. SerializeObject(component);
  40. }
  41. private static object SerializeObject(Object unityObject)
  42. {
  43. var serializedObject = new SerializedObject(unityObject);
  44. var propertyIterator = serializedObject.GetIterator();
  45. var propertyData = new Dictionary<string, object>();
  46. // Use a do-while loop to ensure the first property is processed
  47. if (propertyIterator.NextVisible(true))
  48. {
  49. do
  50. {
  51. propertyData[propertyIterator.name] = GetValueFromProperty(propertyIterator);
  52. } while (propertyIterator.NextVisible(false));
  53. }
  54. return propertyData;
  55. }
  56. private static object GetValueFromProperty(SerializedProperty property)
  57. {
  58. // This is a simplified version. A full implementation would handle all property types.
  59. return property.propertyType switch
  60. {
  61. SerializedPropertyType.Integer => property.longValue,
  62. SerializedPropertyType.Boolean => property.boolValue,
  63. SerializedPropertyType.Float => property.doubleValue,
  64. SerializedPropertyType.String => property.stringValue,
  65. SerializedPropertyType.Color => property.colorValue,
  66. SerializedPropertyType.ObjectReference => GetObjectReferenceValue(property),
  67. SerializedPropertyType.Enum => property.enumNames[property.enumValueIndex],
  68. SerializedPropertyType.Vector2 => property.vector2Value,
  69. SerializedPropertyType.Vector3 => property.vector3Value,
  70. SerializedPropertyType.Vector4 => property.vector4Value,
  71. SerializedPropertyType.Rect => property.rectValue,
  72. SerializedPropertyType.AnimationCurve => property.animationCurveValue,
  73. SerializedPropertyType.Bounds => property.boundsValue,
  74. SerializedPropertyType.Quaternion => property.quaternionValue,
  75. _ => $"Unsupported Type: {property.propertyType}"
  76. };
  77. }
  78. private static object GetObjectReferenceValue(SerializedProperty property)
  79. {
  80. var obj = property.objectReferenceValue;
  81. if (obj == null) return null;
  82. return new { name = obj.name, id = GetStableIdForObject(obj) };
  83. }
  84. private static string GetStableIdForObject(Object obj)
  85. {
  86. if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _))
  87. {
  88. if (!string.IsNullOrEmpty(guid) && guid != "00000000000000000000000000000000")
  89. {
  90. return guid;
  91. }
  92. }
  93. return obj.GetInstanceID().ToString();
  94. }
  95. private static Type GetTypeByName(string typeName)
  96. {
  97. foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
  98. {
  99. var type = assembly.GetType(typeName);
  100. if (type != null) return type;
  101. }
  102. return null;
  103. }
  104. }
  105. }