116 lines
4.9 KiB
C#
116 lines
4.9 KiB
C#
#nullable disable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using MCPForUnity.Editor.Helpers; // For Response class
|
|
using Newtonsoft.Json.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace MCPForUnity.Editor.Tools.GameObjects
|
|
{
|
|
/// <summary>
|
|
/// Handles GameObject manipulation within the current scene (CRUD, find, components).
|
|
/// </summary>
|
|
[McpForUnityTool("manage_gameobject", AutoRegister = false)]
|
|
public static class ManageGameObject
|
|
{
|
|
// --- Main Handler ---
|
|
|
|
public static object HandleCommand(JObject @params)
|
|
{
|
|
if (@params == null)
|
|
{
|
|
return new ErrorResponse("Parameters cannot be null.");
|
|
}
|
|
|
|
string action = @params["action"]?.ToString().ToLower();
|
|
if (string.IsNullOrEmpty(action))
|
|
{
|
|
return new ErrorResponse("Action parameter is required.");
|
|
}
|
|
|
|
// Parameters used by various actions
|
|
JToken targetToken = @params["target"]; // Can be string (name/path) or int (instanceID)
|
|
string name = @params["name"]?.ToString();
|
|
|
|
// --- Usability Improvement: Alias 'name' to 'target' for modification actions ---
|
|
// If 'target' is missing but 'name' is provided, and we aren't creating a new object,
|
|
// assume the user meant "find object by name".
|
|
if (targetToken == null && !string.IsNullOrEmpty(name) && action != "create")
|
|
{
|
|
targetToken = name;
|
|
// We don't update @params["target"] because we use targetToken locally mostly,
|
|
// but some downstream methods might parse @params directly. Let's update @params too for safety.
|
|
@params["target"] = name;
|
|
}
|
|
// -------------------------------------------------------------------------------
|
|
|
|
string searchMethod = @params["searchMethod"]?.ToString().ToLower();
|
|
string tag = @params["tag"]?.ToString();
|
|
string layer = @params["layer"]?.ToString();
|
|
JToken parentToken = @params["parent"];
|
|
|
|
// Coerce string JSON to JObject for 'componentProperties' if provided as a JSON string
|
|
var componentPropsToken = @params["componentProperties"];
|
|
if (componentPropsToken != null && componentPropsToken.Type == JTokenType.String)
|
|
{
|
|
try
|
|
{
|
|
var parsed = JObject.Parse(componentPropsToken.ToString());
|
|
@params["componentProperties"] = parsed;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
McpLog.Warn($"[ManageGameObject] Could not parse 'componentProperties' JSON string: {e.Message}");
|
|
}
|
|
}
|
|
|
|
// --- Prefab Asset Check ---
|
|
// Prefab assets require different tools. Only 'create' (instantiation) is valid here.
|
|
string targetPath =
|
|
targetToken?.Type == JTokenType.String ? targetToken.ToString() : null;
|
|
if (
|
|
!string.IsNullOrEmpty(targetPath)
|
|
&& targetPath.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase)
|
|
&& action != "create" // Allow prefab instantiation
|
|
)
|
|
{
|
|
return new ErrorResponse(
|
|
$"Target '{targetPath}' is a prefab asset. " +
|
|
$"Use 'manage_asset' with action='modify' for prefab asset modifications, " +
|
|
$"or 'manage_prefabs' with action='open_stage' to edit the prefab in isolation mode."
|
|
);
|
|
}
|
|
// --- End Prefab Asset Check ---
|
|
|
|
try
|
|
{
|
|
switch (action)
|
|
{
|
|
// --- Primary lifecycle actions (kept in manage_gameobject) ---
|
|
case "create":
|
|
return GameObjectCreate.Handle(@params);
|
|
case "modify":
|
|
return GameObjectModify.Handle(@params, targetToken, searchMethod);
|
|
case "delete":
|
|
return GameObjectDelete.Handle(targetToken, searchMethod);
|
|
case "duplicate":
|
|
return GameObjectDuplicate.Handle(@params, targetToken, searchMethod);
|
|
case "move_relative":
|
|
return GameObjectMoveRelative.Handle(@params, targetToken, searchMethod);
|
|
|
|
default:
|
|
return new ErrorResponse($"Unknown action: '{action}'.");
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
McpLog.Error($"[ManageGameObject] Action '{action}' failed: {e}");
|
|
return new ErrorResponse($"Internal error processing action '{action}': {e.Message}");
|
|
}
|
|
}
|
|
}
|
|
}
|