Update for ManageShader

Bug fix and error handling check for the PR. Great work and I love what I built!
main
Scriptwonder 2025-07-14 01:42:16 -04:00
parent d4bd504e31
commit 55f7c55389
5 changed files with 79 additions and 46 deletions

View File

@ -25,6 +25,7 @@ Unity MCP acts as a bridge, allowing AI assistants (like Claude, Cursor) to inte
* `manage_editor`: Controls and queries the editor's state and settings.
* `manage_scene`: Manages scenes (load, save, create, get hierarchy, etc.).
* `manage_asset`: Performs asset operations (import, create, modify, delete, etc.).
* `manage_shader`: Performs shader CRUD operations (create, read, modify, delete).
* `manage_gameobject`: Manages GameObjects: create, modify, delete, find, and component operations.
* `execute_menu_item`: Executes a menu item via its path (e.g., "File/Save Project").
</details>
@ -81,7 +82,9 @@ Unity MCP connects your tools using two components:
Connect your MCP Client (Claude, Cursor, etc.) to the Python server you installed in Step 1.
**Option A: Auto-Configure (Recommended for Claude/Cursor)**
<img width="609" alt="image" src="https://github.com/user-attachments/assets/cef3a639-4677-4fd8-84e7-2d82a04d55bb" />
**Option A: Auto-Configure (Recommended for Claude/Cursor/VSC Copilot)**
1. In Unity, go to `Window > Unity MCP`.
2. Click `Auto Configure Claude` or `Auto Configure Cursor`.

View File

@ -20,6 +20,7 @@ namespace UnityMcpBridge.Editor.Tools
{ "HandleManageAsset", ManageAsset.HandleCommand },
{ "HandleReadConsole", ReadConsole.HandleCommand },
{ "HandleExecuteMenuItem", ExecuteMenuItem.HandleCommand },
{ "HandleManageShader", ManageShader.HandleCommand},
};
/// <summary>

View File

@ -89,7 +89,12 @@ namespace UnityMcpBridge.Editor.Tools
{
try
{
Directory.CreateDirectory(fullPathDir);
if (!Directory.Exists(fullPathDir))
{
Directory.CreateDirectory(fullPathDir);
// Refresh AssetDatabase to recognize new folders
AssetDatabase.Refresh();
}
}
catch (Exception e)
{
@ -150,6 +155,14 @@ namespace UnityMcpBridge.Editor.Tools
);
}
// Add validation for shader name conflicts in Unity
if (Shader.Find(name) != null)
{
return Response.Error(
$"A shader with name '{name}' already exists in the project. Choose a different name."
);
}
// Generate default content if none provided
if (string.IsNullOrEmpty(contents))
{
@ -184,6 +197,7 @@ namespace UnityMcpBridge.Editor.Tools
string contents = File.ReadAllText(fullPath);
// Return both normal and encoded contents for larger files
//TODO: Consider a threshold for large files
bool isLarge = contents.Length > 10000; // If content is large, include encoded version
var responseData = new
{
@ -227,6 +241,7 @@ namespace UnityMcpBridge.Editor.Tools
{
File.WriteAllText(fullPath, contents);
AssetDatabase.ImportAsset(relativePath);
AssetDatabase.Refresh();
return Response.Success(
$"Shader '{Path.GetFileName(relativePath)}' updated successfully.",
new { path = relativePath }
@ -268,58 +283,60 @@ namespace UnityMcpBridge.Editor.Tools
}
}
//This is a CGProgram template
//TODO: making a HLSL template as well?
private static string GenerateDefaultShaderContent(string name)
{
return @"Shader """ + name + @"""
{
Properties
{
_MainTex (""Texture"", 2D) = ""white"" {}
}
SubShader
{
Tags { ""RenderType""=""Opaque"" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include ""UnityCG.cginc""
struct appdata
Properties
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
_MainTex (""Texture"", 2D) = ""white"" {}
}
fixed4 frag (v2f i) : SV_Target
SubShader
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
Tags { ""RenderType""=""Opaque"" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include ""UnityCG.cginc""
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
ENDCG
}
}
}";
}";
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bcf4f1f3110494344b2af9324cf5c571
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -378,6 +378,7 @@ namespace UnityMcpBridge.Editor
"manage_editor" => ManageEditor.HandleCommand(paramsObject),
"manage_gameobject" => ManageGameObject.HandleCommand(paramsObject),
"manage_asset" => ManageAsset.HandleCommand(paramsObject),
"manage_shader" => ManageShader.HandleCommand(paramsObject),
"read_console" => ReadConsole.HandleCommand(paramsObject),
"execute_menu_item" => ExecuteMenuItem.HandleCommand(paramsObject),
_ => throw new ArgumentException(