using System;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using Object = UnityEngine.Object;
namespace LLM.Editor.Analysis
{
///
/// Provides detailed, serialized data for a specific component on a GameObject.
///
public class ComponentDataProvider : IContextProvider
{
public object GetContext(Object target, string qualifier)
{
if (target is not GameObject go)
{
return "Error: Target must be a GameObject to get component data.";
}
if (string.IsNullOrEmpty(qualifier))
{
return "Error: Component type name (qualifier) is required.";
}
var componentType = GetTypeByName(qualifier);
if (componentType == null)
{
return $"Error: Component type '{qualifier}' not found.";
}
Component component;
try
{
component = go.GetComponent(componentType);
}
catch (Exception exception)
{
return $"Error: Failed to get component '{qualifier}': {exception.Message}";
}
return !component ? $"Error: Component '{qualifier}' not found on GameObject '{go.name}'." :
// Reuse the generic serialization logic for any component.
SerializeObject(component);
}
private static object SerializeObject(Object unityObject)
{
var serializedObject = new SerializedObject(unityObject);
var propertyIterator = serializedObject.GetIterator();
var propertyData = new Dictionary();
// Use a do-while loop to ensure the first property is processed
if (propertyIterator.NextVisible(true))
{
do
{
propertyData[propertyIterator.name] = GetValueFromProperty(propertyIterator);
} while (propertyIterator.NextVisible(false));
}
return propertyData;
}
private static object GetValueFromProperty(SerializedProperty property)
{
// This is a simplified version. A full implementation would handle all property types.
return property.propertyType switch
{
SerializedPropertyType.Integer => property.longValue,
SerializedPropertyType.Boolean => property.boolValue,
SerializedPropertyType.Float => property.doubleValue,
SerializedPropertyType.String => property.stringValue,
SerializedPropertyType.Color => property.colorValue,
SerializedPropertyType.ObjectReference => GetObjectReferenceValue(property),
SerializedPropertyType.Enum => property.enumNames[property.enumValueIndex],
SerializedPropertyType.Vector2 => property.vector2Value,
SerializedPropertyType.Vector3 => property.vector3Value,
SerializedPropertyType.Vector4 => property.vector4Value,
SerializedPropertyType.Rect => property.rectValue,
SerializedPropertyType.AnimationCurve => property.animationCurveValue,
SerializedPropertyType.Bounds => property.boundsValue,
SerializedPropertyType.Quaternion => property.quaternionValue,
_ => $"Unsupported Type: {property.propertyType}"
};
}
private static object GetObjectReferenceValue(SerializedProperty property)
{
var obj = property.objectReferenceValue;
if (obj == null) return null;
return new { name = obj.name, id = GetStableIdForObject(obj) };
}
private static string GetStableIdForObject(Object obj)
{
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(obj, out var guid, out long _))
{
if (!string.IsNullOrEmpty(guid) && guid != "00000000000000000000000000000000")
{
return guid;
}
}
return obj.GetInstanceID().ToString();
}
private static Type GetTypeByName(string typeName)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var type = assembly.GetType(typeName);
if (type != null) return type;
}
return null;
}
}
}