Skip to main content
Glama
SerializedPropertyWriter.cs7.77 kB
using System; using UnityEngine; using UnityEditor; namespace LocalMcp.UnityServer { /// <summary> /// Provides SerializedProperty write capabilities for private/protected/SerializeField access /// </summary> public static class SerializedPropertyWriter { /// <summary> /// Sets a serialized property value (supports private/protected fields with SerializeField) /// </summary> public static string SetSerializedProperty(string paramsJson, object id) { try { var parameters = JsonUtility.FromJson<SetSerializedPropertyParams>(paramsJson); if (string.IsNullOrEmpty(parameters.gameObjectPath)) { return JsonRpcResponseHelper.InvalidParams("gameObjectPath is required", id); } if (string.IsNullOrEmpty(parameters.componentType)) { return JsonRpcResponseHelper.InvalidParams("componentType is required", id); } if (string.IsNullOrEmpty(parameters.propertyPath)) { return JsonRpcResponseHelper.InvalidParams("propertyPath is required", id); } GameObject go = GameObject.Find(parameters.gameObjectPath); if (go == null) { return JsonRpcResponseHelper.ErrorMessage($"GameObject '{parameters.gameObjectPath}' not found", id); } Component component = go.GetComponent(parameters.componentType); if (component == null) { return JsonRpcResponseHelper.ErrorMessage($"Component '{parameters.componentType}' not found on GameObject", id); } // Create SerializedObject SerializedObject serializedObject = new SerializedObject(component); SerializedProperty property = serializedObject.FindProperty(parameters.propertyPath); if (property == null) { return JsonRpcResponseHelper.ErrorMessage($"Property '{parameters.propertyPath}' not found", id); } // Set value based on property type bool success = SetPropertyValue(property, parameters.value, parameters.valueType); if (!success) { return JsonRpcResponseHelper.ErrorMessage($"Failed to set property value. Property type: {property.propertyType}", id); } // Apply changes serializedObject.ApplyModifiedProperties(); var result = new SetSerializedPropertyResult { success = true, gameObjectPath = parameters.gameObjectPath, componentType = parameters.componentType, propertyPath = parameters.propertyPath, propertyType = property.propertyType.ToString() }; var response = JsonRpcResponse.Success(result, id); return response.ToJson(); } catch (Exception e) { Debug.LogError($"[MCP] SetSerializedProperty error: {e.Message}\n{e.StackTrace}"); return JsonRpcResponseHelper.ErrorMessage($"Failed to set serialized property: {e.Message}", id); } } private static bool SetPropertyValue(SerializedProperty property, string value, string valueType) { try { switch (property.propertyType) { case SerializedPropertyType.Integer: property.intValue = Convert.ToInt32(value); return true; case SerializedPropertyType.Boolean: property.boolValue = Convert.ToBoolean(value); return true; case SerializedPropertyType.Float: property.floatValue = Convert.ToSingle(value); return true; case SerializedPropertyType.String: property.stringValue = value; return true; case SerializedPropertyType.Color: var colorData = JsonUtility.FromJson<ColorData>(value); property.colorValue = new Color(colorData.r, colorData.g, colorData.b, colorData.a); return true; case SerializedPropertyType.Vector2: var vec2Data = JsonUtility.FromJson<Vector2Data>(value); property.vector2Value = new Vector2(vec2Data.x, vec2Data.y); return true; case SerializedPropertyType.Vector3: var vec3Data = JsonUtility.FromJson<Vector3Data>(value); property.vector3Value = new Vector3(vec3Data.x, vec3Data.y, vec3Data.z); return true; case SerializedPropertyType.Vector4: var vec4Data = JsonUtility.FromJson<Vector4Data>(value); property.vector4Value = new Vector4(vec4Data.x, vec4Data.y, vec4Data.z, vec4Data.w); return true; case SerializedPropertyType.Enum: property.enumValueIndex = Convert.ToInt32(value); return true; case SerializedPropertyType.ObjectReference: // For object references, value should be asset path if (!string.IsNullOrEmpty(value)) { var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(value); if (obj != null) { property.objectReferenceValue = obj; return true; } } else { // Set to null property.objectReferenceValue = null; return true; } return false; default: Debug.LogWarning($"[MCP] Unsupported property type: {property.propertyType}"); return false; } } catch (Exception e) { Debug.LogError($"[MCP] SetPropertyValue error: {e.Message}"); return false; } } } #region Data Structures [Serializable] public class SetSerializedPropertyParams { public string gameObjectPath; public string componentType; public string propertyPath; // e.g., "m_Speed", "settings.maxValue" public string value; // String representation of the value public string valueType; // Optional: "int", "float", "bool", "string", "vector3", etc. } [Serializable] public class SetSerializedPropertyResult { public bool success; public string gameObjectPath; public string componentType; public string propertyPath; public string propertyType; } [Serializable] public class ColorData { public float r; public float g; public float b; public float a; } // Note: Vector2Data, Vector3Data, Vector4Data are defined in SceneSetupCommand.cs #endregion }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dsgarage/UniMCP4CC'

If you have feedback or need assistance with the MCP directory API, please join our Discord server