using System;
using System.Collections.Generic;
using System.Linq;
using MCPForUnity.Editor.Helpers;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEngine;
namespace MCPForUnity.Editor.Resources.Scene
{
///
/// Resource handler for reading GameObject data.
/// Provides read-only access to GameObject information without component serialization.
///
/// URI: unity://scene/gameobject/{instanceID}
///
[McpForUnityResource("get_gameobject")]
public static class GameObjectResource
{
public static object HandleCommand(JObject @params)
{
if (@params == null)
{
return new ErrorResponse("Parameters cannot be null.");
}
// Get instance ID from params
int? instanceID = null;
var idToken = @params["instanceID"] ?? @params["instance_id"] ?? @params["id"];
if (idToken != null)
{
instanceID = ParamCoercion.CoerceInt(idToken, -1);
if (instanceID == -1)
{
instanceID = null;
}
}
if (!instanceID.HasValue)
{
return new ErrorResponse("'instanceID' parameter is required.");
}
try
{
var go = EditorUtility.InstanceIDToObject(instanceID.Value) as GameObject;
if (go == null)
{
return new ErrorResponse($"GameObject with instance ID {instanceID} not found.");
}
return new
{
success = true,
data = SerializeGameObject(go)
};
}
catch (Exception e)
{
McpLog.Error($"[GameObjectResource] Error getting GameObject: {e}");
return new ErrorResponse($"Error getting GameObject: {e.Message}");
}
}
///
/// Serializes a GameObject without component details.
/// For component data, use GetComponents or GetComponent resources.
///
public static object SerializeGameObject(GameObject go)
{
if (go == null)
return null;
var transform = go.transform;
// Get component type names (not full serialization)
var componentTypes = go.GetComponents()
.Where(c => c != null)
.Select(c => c.GetType().Name)
.ToList();
// Get children instance IDs (not full serialization)
var childrenIds = new List();
foreach (Transform child in transform)
{
childrenIds.Add(child.gameObject.GetInstanceID());
}
return new
{
instanceID = go.GetInstanceID(),
name = go.name,
tag = go.tag,
layer = go.layer,
layerName = LayerMask.LayerToName(go.layer),
active = go.activeSelf,
activeInHierarchy = go.activeInHierarchy,
isStatic = go.isStatic,
transform = new
{
position = SerializeVector3(transform.position),
localPosition = SerializeVector3(transform.localPosition),
rotation = SerializeVector3(transform.eulerAngles),
localRotation = SerializeVector3(transform.localEulerAngles),
scale = SerializeVector3(transform.localScale),
lossyScale = SerializeVector3(transform.lossyScale)
},
parent = transform.parent != null ? transform.parent.gameObject.GetInstanceID() : (int?)null,
children = childrenIds,
componentTypes = componentTypes,
path = GameObjectLookup.GetGameObjectPath(go)
};
}
private static object SerializeVector3(Vector3 v)
{
return new { x = v.x, y = v.y, z = v.z };
}
}
///
/// Resource handler for reading all components on a GameObject.
///
/// URI: unity://scene/gameobject/{instanceID}/components
///
[McpForUnityResource("get_gameobject_components")]
public static class GameObjectComponentsResource
{
public static object HandleCommand(JObject @params)
{
if (@params == null)
{
return new ErrorResponse("Parameters cannot be null.");
}
var idToken = @params["instanceID"] ?? @params["instance_id"] ?? @params["id"];
int instanceID = ParamCoercion.CoerceInt(idToken, -1);
if (instanceID == -1)
{
return new ErrorResponse("'instanceID' parameter is required.");
}
// Pagination parameters
int pageSize = ParamCoercion.CoerceInt(@params["pageSize"] ?? @params["page_size"], 25);
int cursor = ParamCoercion.CoerceInt(@params["cursor"], 0);
bool includeProperties = ParamCoercion.CoerceBool(@params["includeProperties"] ?? @params["include_properties"], true);
pageSize = Mathf.Clamp(pageSize, 1, 100);
try
{
var go = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (go == null)
{
return new ErrorResponse($"GameObject with instance ID {instanceID} not found.");
}
var allComponents = go.GetComponents().Where(c => c != null).ToList();
int total = allComponents.Count;
var pagedComponents = allComponents.Skip(cursor).Take(pageSize).ToList();
var componentData = new List