diff --git a/MCPForUnity/Editor/Helpers/ComponentOps.cs b/MCPForUnity/Editor/Helpers/ComponentOps.cs index 97e8a2b76..57a7a57da 100644 --- a/MCPForUnity/Editor/Helpers/ComponentOps.cs +++ b/MCPForUnity/Editor/Helpers/ComponentOps.cs @@ -197,11 +197,21 @@ private static bool TrySetViaReflection(object component, Type type, string prop { error = null; + // Skip reflection for UnityEngine.Object types with JObject values + // so SerializedProperty can resolve guid/spriteName/fileID forms. + bool isJObjectValue = value != null && value.Type == JTokenType.Object; + // Try property first PropertyInfo propInfo = type.GetProperty(propertyName, flags) ?? type.GetProperty(normalizedName, flags); if (propInfo != null && propInfo.CanWrite) { + if (isJObjectValue && typeof(UnityEngine.Object).IsAssignableFrom(propInfo.PropertyType)) + { + // Let SerializedProperty path handle complex object references. + return false; + } + try { object convertedValue = PropertyConversion.ConvertToType(value, propInfo.PropertyType); @@ -225,6 +235,12 @@ private static bool TrySetViaReflection(object component, Type type, string prop ?? type.GetField(normalizedName, flags); if (fieldInfo != null && !fieldInfo.IsInitOnly) { + if (isJObjectValue && typeof(UnityEngine.Object).IsAssignableFrom(fieldInfo.FieldType)) + { + // Let SerializedProperty path handle complex object references. + return false; + } + try { object convertedValue = PropertyConversion.ConvertToType(value, fieldInfo.FieldType); @@ -248,6 +264,12 @@ private static bool TrySetViaReflection(object component, Type type, string prop ?? FindSerializedFieldInHierarchy(type, normalizedName); if (fieldInfo != null) { + if (isJObjectValue && typeof(UnityEngine.Object).IsAssignableFrom(fieldInfo.FieldType)) + { + // Let SerializedProperty path handle complex object references. + return false; + } + try { object convertedValue = PropertyConversion.ConvertToType(value, fieldInfo.FieldType); @@ -599,6 +621,50 @@ private static bool SetObjectReference(SerializedProperty prop, JToken value, ou error = $"No asset found for GUID '{guidToken}'."; return false; } + + var spriteNameToken = jObj["spriteName"]; + if (spriteNameToken != null) + { + string spriteName = spriteNameToken.ToString(); + var allAssets = AssetDatabase.LoadAllAssetsAtPath(path); + foreach (var asset in allAssets) + { + if (asset is Sprite sprite && sprite.name == spriteName) + { + prop.objectReferenceValue = sprite; + return true; + } + } + + error = $"Sprite '{spriteName}' not found in atlas '{path}'."; + return false; + } + + var fileIdToken = jObj["fileID"]; + if (fileIdToken != null) + { + long targetFileId = fileIdToken.Value(); + if (targetFileId != 0) + { + var allAssets = AssetDatabase.LoadAllAssetsAtPath(path); + foreach (var asset in allAssets) + { + if (asset is Sprite sprite) + { + long spriteFileId = GetSpriteFileId(sprite); + if (spriteFileId == targetFileId) + { + prop.objectReferenceValue = sprite; + return true; + } + } + } + } + + error = $"Sprite with fileID '{targetFileId}' not found in atlas '{path}'."; + return false; + } + prop.objectReferenceValue = AssetDatabase.LoadAssetAtPath(path); return true; } @@ -767,6 +833,23 @@ private static bool SetEnum(SerializedProperty prop, JToken value, out string er error = $"Unknown enum name '{s}'."; return false; } + + private static long GetSpriteFileId(Sprite sprite) + { + if (sprite == null) + return 0; + + try + { + var globalId = GlobalObjectId.GetGlobalObjectIdSlow(sprite); + return unchecked((long)globalId.targetObjectId); + } + catch (Exception ex) + { + McpLog.Warn($"Failed to get fileID for sprite '{sprite.name}' (instanceID={sprite.GetInstanceID()}): {ex.Message}"); + return 0; + } + } } }