Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/skills/unity-mcp-skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,11 @@ uri="file:///full/path/to/file.cs"
| **Objects** | `manage_gameobject`, `manage_components` | Creating/modifying GameObjects |
| **Scripts** | `create_script`, `script_apply_edits`, `refresh_unity` | C# code management |
| **Assets** | `manage_asset`, `manage_prefabs` | Asset operations |
| **Editor** | `manage_editor`, `execute_menu_item`, `read_console` | Editor control |
| **Editor** | `manage_editor`, `execute_menu_item`, `read_console` | Editor control, package deployment (`deploy_package`/`restore_package` actions) |
| **Testing** | `run_tests`, `get_test_job` | Unity Test Framework |
| **Batch** | `batch_execute` | Parallel/bulk operations |
| **Camera** | `manage_camera` | Camera management (Unity Camera + Cinemachine). **Tier 1** (always available): create, target, lens, priority, list, screenshot. **Tier 2** (requires `com.unity.cinemachine`): brain, body/aim/noise pipeline, extensions, blending, force/release. 7 presets: follow, third_person, freelook, dolly, static, top_down, side_scroller. Resource: `mcpforunity://scene/cameras`. Use `ping` to check Cinemachine availability. See [tools-reference.md](references/tools-reference.md#camera-tools). |
| **Graphics** | `manage_graphics` | Rendering and post-processing management. 33 actions across 5 groups: **Volume** (create/configure volumes and effects, URP/HDRP), **Bake** (lightmaps, light probes, reflection probes, Edit mode only), **Stats** (draw calls, batches, memory), **Pipeline** (quality levels, pipeline settings), **Features** (URP renderer features: add, remove, toggle, reorder). Resources: `mcpforunity://scene/volumes`, `mcpforunity://rendering/stats`, `mcpforunity://pipeline/renderer-features`. Use `ping` to check pipeline status. See [tools-reference.md](references/tools-reference.md#graphics-tools). |
| **ProBuilder** | `manage_probuilder` | 3D modeling, mesh editing, complex geometry. **When `com.unity.probuilder` is installed, prefer ProBuilder shapes over primitive GameObjects** for editable geometry, multi-material faces, or complex shapes. Supports 12 shape types, face/edge/vertex editing, smoothing, and per-face materials. See [ProBuilder Guide](references/probuilder-guide.md). |
| **UI** | `manage_ui`, `batch_execute` with `manage_gameobject` + `manage_components` | **UI Toolkit**: Use `manage_ui` to create UXML/USS files, attach UIDocument, inspect visual trees. **uGUI (Canvas)**: Use `batch_execute` for Canvas, Panel, Button, Text, Slider, Toggle, Input Field. **Read `mcpforunity://project/info` first** to detect uGUI/TMP/Input System/UI Toolkit availability. (see [UI workflows](references/workflows.md#ui-creation-workflows)) |

Expand Down
4 changes: 4 additions & 0 deletions MCPForUnity/Editor/Helpers/AssetPathUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ public static string SanitizeAssetPath(string path)
}

// Ensure path starts with Assets/
if (string.Equals(path, "Assets", StringComparison.OrdinalIgnoreCase))
{
return "Assets";
}
if (!path.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase))
{
return "Assets/" + path.TrimStart('/');
Expand Down
4 changes: 2 additions & 2 deletions MCPForUnity/Editor/Helpers/ComponentOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ private static bool SetObjectReference(SerializedProperty prop, JToken value, ou
if (value.Type == JTokenType.Integer)
{
int id = value.Value<int>();
var resolved = EditorUtility.InstanceIDToObject(id);
var resolved = GameObjectLookup.ResolveInstanceID(id);
if (resolved == null)
{
error = $"No object found with instanceID {id}.";
Expand All @@ -580,7 +580,7 @@ private static bool SetObjectReference(SerializedProperty prop, JToken value, ou
if (idToken != null)
{
int id = ParamCoercion.CoerceInt(idToken, 0);
var resolved = EditorUtility.InstanceIDToObject(id);
var resolved = GameObjectLookup.ResolveInstanceID(id);
if (resolved == null)
{
error = $"No object found with instanceID {id}.";
Expand Down
20 changes: 14 additions & 6 deletions MCPForUnity/Editor/Helpers/GameObjectLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,24 @@ public static GameObject FindByTarget(JToken target, string searchMethod, bool i
return results.Count > 0 ? FindById(results[0]) : null;
}

/// <summary>
/// Resolves an instance ID to a UnityEngine.Object.
/// </summary>
public static UnityEngine.Object ResolveInstanceID(int instanceId)
{
#if UNITY_6000_3_OR_NEWER
return EditorUtility.EntityIdToObject(instanceId);
#else
return EditorUtility.InstanceIDToObject(instanceId);
#endif
}

/// <summary>
/// Finds a GameObject by its instance ID.
/// </summary>
public static GameObject FindById(int instanceId)
{
#pragma warning disable CS0618 // Type or member is obsolete
return EditorUtility.InstanceIDToObject(instanceId) as GameObject;
#pragma warning restore CS0618
return ResolveInstanceID(instanceId) as GameObject;
}

/// <summary>
Expand Down Expand Up @@ -105,9 +115,7 @@ public static List<int> SearchGameObjects(SearchMethod method, string searchTerm
case SearchMethod.ById:
if (int.TryParse(searchTerm, out int instanceId))
{
#pragma warning disable CS0618 // Type or member is obsolete
var obj = EditorUtility.InstanceIDToObject(instanceId) as GameObject;
#pragma warning restore CS0618
var obj = ResolveInstanceID(instanceId) as GameObject;
if (obj != null && (includeInactive || obj.activeInHierarchy))
{
results.Add(instanceId);
Expand Down
2 changes: 1 addition & 1 deletion MCPForUnity/Editor/Resources/Editor/Selection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static object HandleCommand(JObject @params)
activeObject = UnityEditor.Selection.activeObject?.name,
activeGameObject = UnityEditor.Selection.activeGameObject?.name,
activeTransform = UnityEditor.Selection.activeTransform?.name,
activeInstanceID = UnityEditor.Selection.activeInstanceID,
activeInstanceID = UnityEditor.Selection.activeObject?.GetInstanceID() ?? 0,
count = UnityEditor.Selection.count,
objects = UnityEditor.Selection.objects
.Select(obj => new
Expand Down
6 changes: 3 additions & 3 deletions MCPForUnity/Editor/Resources/Scene/GameObjectResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static object HandleCommand(JObject @params)

try
{
var go = EditorUtility.InstanceIDToObject(instanceID.Value) as GameObject;
var go = GameObjectLookup.ResolveInstanceID(instanceID.Value) as GameObject;
if (go == null)
{
return new ErrorResponse($"GameObject with instance ID {instanceID} not found.");
Expand Down Expand Up @@ -150,7 +150,7 @@ public static object HandleCommand(JObject @params)

try
{
var go = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
var go = GameObjectLookup.ResolveInstanceID(instanceID) as GameObject;
if (go == null)
{
return new ErrorResponse($"GameObject with instance ID {instanceID} not found.");
Expand Down Expand Up @@ -235,7 +235,7 @@ public static object HandleCommand(JObject @params)

try
{
var go = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
var go = GameObjectLookup.ResolveInstanceID(instanceID) as GameObject;
if (go == null)
{
return new ErrorResponse($"GameObject with instance ID {instanceID} not found.");
Expand Down
24 changes: 24 additions & 0 deletions MCPForUnity/Editor/Resources/Scene/RendererFeaturesResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using MCPForUnity.Editor.Helpers;
using MCPForUnity.Editor.Tools.Graphics;
using Newtonsoft.Json.Linq;

namespace MCPForUnity.Editor.Resources.Scene
{
[McpForUnityResource("get_renderer_features")]
public static class RendererFeaturesResource
{
public static object HandleCommand(JObject @params)
{
try
{
return RendererFeatureOps.ListFeatures(@params ?? new JObject());
}
catch (Exception e)
{
McpLog.Error($"[RendererFeaturesResource] Error: {e}");
return new ErrorResponse($"Error listing renderer features: {e.Message}");
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions MCPForUnity/Editor/Resources/Scene/RenderingStatsResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using MCPForUnity.Editor.Helpers;
using MCPForUnity.Editor.Tools.Graphics;
using Newtonsoft.Json.Linq;

namespace MCPForUnity.Editor.Resources.Scene
{
[McpForUnityResource("get_rendering_stats")]
public static class RenderingStatsResource
{
public static object HandleCommand(JObject @params)
{
try
{
return RenderingStatsOps.GetStats(@params ?? new JObject());
}
catch (Exception e)
{
McpLog.Error($"[RenderingStatsResource] Error: {e}");
return new ErrorResponse($"Error getting rendering stats: {e.Message}");
}
}
}
}
11 changes: 11 additions & 0 deletions MCPForUnity/Editor/Resources/Scene/RenderingStatsResource.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions MCPForUnity/Editor/Resources/Scene/VolumesResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using MCPForUnity.Editor.Helpers;
using MCPForUnity.Editor.Tools.Graphics;
using Newtonsoft.Json.Linq;

namespace MCPForUnity.Editor.Resources.Scene
{
[McpForUnityResource("get_volumes")]
public static class VolumesResource
{
public static object HandleCommand(JObject @params)
{
try
{
return VolumeOps.ListVolumes(@params ?? new JObject());
}
catch (Exception e)
{
McpLog.Error($"[VolumesResource] Error listing volumes: {e}");
return new ErrorResponse($"Error listing volumes: {e.Message}");
}
}
}
}
11 changes: 11 additions & 0 deletions MCPForUnity/Editor/Resources/Scene/VolumesResource.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions MCPForUnity/Editor/Tools/Cameras/CameraControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,23 @@ internal static class CameraControl
{
internal static object ListCameras(JObject @params)
{
#if UNITY_2022_2_OR_NEWER
var unityCameras = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(FindObjectsSortMode.None);
#else
var unityCameras = UnityEngine.Object.FindObjectsOfType<UnityEngine.Camera>();
#endif
var cameraList = new List<object>();
var unityCamList = new List<object>();

// Cinemachine cameras
if (CameraHelpers.HasCinemachine)
{
var cmType = CameraHelpers.CinemachineCameraType;
#if UNITY_2022_2_OR_NEWER
var allCm = UnityEngine.Object.FindObjectsByType(cmType, FindObjectsSortMode.None);
#else
var allCm = UnityEngine.Object.FindObjectsOfType(cmType);
#endif
foreach (Component cm in allCm)
{
var follow = CameraHelpers.GetReflectionProperty(cm, "Follow") as Transform;
Expand Down
8 changes: 8 additions & 0 deletions MCPForUnity/Editor/Tools/Cameras/CameraHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,23 @@ internal static Component FindBrain()
if (!HasCinemachine || _cmBrainType == null)
return null;

#if UNITY_2022_2_OR_NEWER
return UnityEngine.Object.FindFirstObjectByType(_cmBrainType) as Component;
#else
return UnityEngine.Object.FindObjectOfType(_cmBrainType) as Component;
#endif
}

internal static UnityEngine.Camera FindMainCamera()
{
var main = UnityEngine.Camera.main;
if (main != null) return main;

#if UNITY_2022_2_OR_NEWER
var allCams = UnityEngine.Object.FindObjectsByType<UnityEngine.Camera>(FindObjectsSortMode.None);
#else
var allCams = UnityEngine.Object.FindObjectsOfType<UnityEngine.Camera>();
#endif
return allCams.Length > 0 ? allCams[0] : null;
}

Expand Down
8 changes: 8 additions & 0 deletions MCPForUnity/Editor/Tools/Graphics.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading