Skip to content

Commit 9fdbd06

Browse files
committed
Initial update
1 parent d01ac7c commit 9fdbd06

25 files changed

Lines changed: 4561 additions & 5 deletions

.claude/skills/unity-mcp-skill/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,11 @@ uri="file:///full/path/to/file.cs"
159159
| **Objects** | `manage_gameobject`, `manage_components` | Creating/modifying GameObjects |
160160
| **Scripts** | `create_script`, `script_apply_edits`, `refresh_unity` | C# code management |
161161
| **Assets** | `manage_asset`, `manage_prefabs` | Asset operations |
162-
| **Editor** | `manage_editor`, `execute_menu_item`, `read_console` | Editor control |
162+
| **Editor** | `manage_editor`, `execute_menu_item`, `read_console` | Editor control, package deployment (`deploy_package`/`restore_package` actions) |
163163
| **Testing** | `run_tests`, `get_test_job` | Unity Test Framework |
164164
| **Batch** | `batch_execute` | Parallel/bulk operations |
165165
| **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). |
166+
| **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). |
166167
| **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). |
167168
| **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)) |
168169

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using MCPForUnity.Editor.Helpers;
3+
using MCPForUnity.Editor.Tools.Graphics;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace MCPForUnity.Editor.Resources.Scene
7+
{
8+
[McpForUnityResource("get_renderer_features")]
9+
public static class RendererFeaturesResource
10+
{
11+
public static object HandleCommand(JObject @params)
12+
{
13+
try
14+
{
15+
return RendererFeatureOps.ListFeatures(@params ?? new JObject());
16+
}
17+
catch (Exception e)
18+
{
19+
McpLog.Error($"[RendererFeaturesResource] Error: {e}");
20+
return new ErrorResponse($"Error listing renderer features: {e.Message}");
21+
}
22+
}
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using MCPForUnity.Editor.Helpers;
3+
using MCPForUnity.Editor.Tools.Graphics;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace MCPForUnity.Editor.Resources.Scene
7+
{
8+
[McpForUnityResource("get_rendering_stats")]
9+
public static class RenderingStatsResource
10+
{
11+
public static object HandleCommand(JObject @params)
12+
{
13+
try
14+
{
15+
return RenderingStatsOps.GetStats(@params ?? new JObject());
16+
}
17+
catch (Exception e)
18+
{
19+
McpLog.Error($"[RenderingStatsResource] Error: {e}");
20+
return new ErrorResponse($"Error getting rendering stats: {e.Message}");
21+
}
22+
}
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using MCPForUnity.Editor.Helpers;
3+
using MCPForUnity.Editor.Tools.Graphics;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace MCPForUnity.Editor.Resources.Scene
7+
{
8+
[McpForUnityResource("get_volumes")]
9+
public static class VolumesResource
10+
{
11+
public static object HandleCommand(JObject @params)
12+
{
13+
try
14+
{
15+
return VolumeOps.ListVolumes(@params ?? new JObject());
16+
}
17+
catch (Exception e)
18+
{
19+
McpLog.Error($"[VolumesResource] Error listing volumes: {e}");
20+
return new ErrorResponse($"Error listing volumes: {e.Message}");
21+
}
22+
}
23+
}
24+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using MCPForUnity.Editor.Helpers;
6+
using Newtonsoft.Json.Linq;
7+
using UnityEditor;
8+
using UnityEngine;
9+
10+
namespace MCPForUnity.Editor.Tools.Graphics
11+
{
12+
internal static class GraphicsHelpers
13+
{
14+
private static bool? _hasVolumeSystem;
15+
private static bool? _hasURP;
16+
private static bool? _hasHDRP;
17+
private static Type _volumeType;
18+
private static Type _volumeProfileType;
19+
private static Type _volumeComponentType;
20+
private static Type _volumeParameterType;
21+
22+
internal static bool HasVolumeSystem
23+
{
24+
get
25+
{
26+
if (_hasVolumeSystem == null) DetectPackages();
27+
return _hasVolumeSystem.Value;
28+
}
29+
}
30+
31+
internal static bool HasURP
32+
{
33+
get
34+
{
35+
if (_hasURP == null) DetectPackages();
36+
return _hasURP.Value;
37+
}
38+
}
39+
40+
internal static bool HasHDRP
41+
{
42+
get
43+
{
44+
if (_hasHDRP == null) DetectPackages();
45+
return _hasHDRP.Value;
46+
}
47+
}
48+
49+
internal static Type VolumeType
50+
{
51+
get
52+
{
53+
if (_hasVolumeSystem == null) DetectPackages();
54+
return _volumeType;
55+
}
56+
}
57+
58+
internal static Type VolumeProfileType
59+
{
60+
get
61+
{
62+
if (_hasVolumeSystem == null) DetectPackages();
63+
return _volumeProfileType;
64+
}
65+
}
66+
67+
internal static Type VolumeComponentType
68+
{
69+
get
70+
{
71+
if (_hasVolumeSystem == null) DetectPackages();
72+
return _volumeComponentType;
73+
}
74+
}
75+
76+
internal static Type VolumeParameterType
77+
{
78+
get
79+
{
80+
if (_hasVolumeSystem == null) DetectPackages();
81+
return _volumeParameterType;
82+
}
83+
}
84+
85+
private static void DetectPackages()
86+
{
87+
_volumeType = Type.GetType("UnityEngine.Rendering.Volume, Unity.RenderPipelines.Core.Runtime");
88+
_volumeProfileType = Type.GetType("UnityEngine.Rendering.VolumeProfile, Unity.RenderPipelines.Core.Runtime");
89+
_volumeComponentType = Type.GetType("UnityEngine.Rendering.VolumeComponent, Unity.RenderPipelines.Core.Runtime");
90+
_volumeParameterType = Type.GetType("UnityEngine.Rendering.VolumeParameter, Unity.RenderPipelines.Core.Runtime");
91+
_hasVolumeSystem = _volumeType != null && _volumeProfileType != null;
92+
93+
var pipeline = RenderPipelineUtility.GetActivePipeline();
94+
_hasURP = pipeline == RenderPipelineUtility.PipelineKind.Universal;
95+
_hasHDRP = pipeline == RenderPipelineUtility.PipelineKind.HighDefinition;
96+
}
97+
98+
internal static Type ResolveVolumeComponentType(string effectName)
99+
{
100+
if (string.IsNullOrEmpty(effectName) || VolumeComponentType == null)
101+
return null;
102+
103+
var derivedTypes = TypeCache.GetTypesDerivedFrom(VolumeComponentType);
104+
foreach (var t in derivedTypes)
105+
{
106+
if (t.IsAbstract) continue;
107+
if (string.Equals(t.Name, effectName, StringComparison.OrdinalIgnoreCase))
108+
return t;
109+
}
110+
return null;
111+
}
112+
113+
internal static List<Type> GetAvailableEffectTypes()
114+
{
115+
if (VolumeComponentType == null)
116+
return new List<Type>();
117+
var derivedTypes = TypeCache.GetTypesDerivedFrom(VolumeComponentType);
118+
return derivedTypes
119+
.Where(t => !t.IsAbstract && !t.IsGenericType)
120+
.OrderBy(t => t.Name)
121+
.ToList();
122+
}
123+
124+
internal static Component FindVolume(JObject @params)
125+
{
126+
var p = new ToolParams(@params);
127+
string target = p.Get("target");
128+
if (string.IsNullOrEmpty(target))
129+
{
130+
var allVolumes = UnityEngine.Object.FindObjectsOfType(VolumeType);
131+
return allVolumes.Length > 0 ? allVolumes[0] as Component : null;
132+
}
133+
134+
if (int.TryParse(target, out int instanceId))
135+
{
136+
var byId = EditorUtility.InstanceIDToObject(instanceId) as GameObject;
137+
if (byId != null) return byId.GetComponent(VolumeType);
138+
}
139+
140+
var go = GameObject.Find(target);
141+
if (go != null) return go.GetComponent(VolumeType);
142+
143+
return null;
144+
}
145+
146+
internal static string GetPipelineName()
147+
{
148+
return RenderPipelineUtility.GetActivePipeline() switch
149+
{
150+
RenderPipelineUtility.PipelineKind.Universal => "Universal (URP)",
151+
RenderPipelineUtility.PipelineKind.HighDefinition => "High Definition (HDRP)",
152+
RenderPipelineUtility.PipelineKind.BuiltIn => "Built-in",
153+
RenderPipelineUtility.PipelineKind.Custom => "Custom",
154+
_ => "Unknown"
155+
};
156+
}
157+
158+
internal static void MarkDirty(UnityEngine.Object obj)
159+
{
160+
if (obj == null) return;
161+
EditorUtility.SetDirty(obj);
162+
if (obj is Component comp)
163+
{
164+
var prefabStage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage();
165+
if (prefabStage != null)
166+
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(prefabStage.scene);
167+
else
168+
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(comp.gameObject.scene);
169+
}
170+
}
171+
}
172+
}

0 commit comments

Comments
 (0)