Update for ManageShader
Bug fix and error handling check for the PR. Great work and I love what I built!main
parent
d4bd504e31
commit
55f7c55389
|
|
@ -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_editor`: Controls and queries the editor's state and settings.
|
||||||
* `manage_scene`: Manages scenes (load, save, create, get hierarchy, etc.).
|
* `manage_scene`: Manages scenes (load, save, create, get hierarchy, etc.).
|
||||||
* `manage_asset`: Performs asset operations (import, create, modify, delete, 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.
|
* `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").
|
* `execute_menu_item`: Executes a menu item via its path (e.g., "File/Save Project").
|
||||||
</details>
|
</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.
|
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`.
|
1. In Unity, go to `Window > Unity MCP`.
|
||||||
2. Click `Auto Configure Claude` or `Auto Configure Cursor`.
|
2. Click `Auto Configure Claude` or `Auto Configure Cursor`.
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ namespace UnityMcpBridge.Editor.Tools
|
||||||
{ "HandleManageAsset", ManageAsset.HandleCommand },
|
{ "HandleManageAsset", ManageAsset.HandleCommand },
|
||||||
{ "HandleReadConsole", ReadConsole.HandleCommand },
|
{ "HandleReadConsole", ReadConsole.HandleCommand },
|
||||||
{ "HandleExecuteMenuItem", ExecuteMenuItem.HandleCommand },
|
{ "HandleExecuteMenuItem", ExecuteMenuItem.HandleCommand },
|
||||||
|
{ "HandleManageShader", ManageShader.HandleCommand},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,12 @@ namespace UnityMcpBridge.Editor.Tools
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(fullPathDir);
|
if (!Directory.Exists(fullPathDir))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(fullPathDir);
|
||||||
|
// Refresh AssetDatabase to recognize new folders
|
||||||
|
AssetDatabase.Refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
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
|
// Generate default content if none provided
|
||||||
if (string.IsNullOrEmpty(contents))
|
if (string.IsNullOrEmpty(contents))
|
||||||
{
|
{
|
||||||
|
|
@ -184,6 +197,7 @@ namespace UnityMcpBridge.Editor.Tools
|
||||||
string contents = File.ReadAllText(fullPath);
|
string contents = File.ReadAllText(fullPath);
|
||||||
|
|
||||||
// Return both normal and encoded contents for larger files
|
// 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
|
bool isLarge = contents.Length > 10000; // If content is large, include encoded version
|
||||||
var responseData = new
|
var responseData = new
|
||||||
{
|
{
|
||||||
|
|
@ -227,6 +241,7 @@ namespace UnityMcpBridge.Editor.Tools
|
||||||
{
|
{
|
||||||
File.WriteAllText(fullPath, contents);
|
File.WriteAllText(fullPath, contents);
|
||||||
AssetDatabase.ImportAsset(relativePath);
|
AssetDatabase.ImportAsset(relativePath);
|
||||||
|
AssetDatabase.Refresh();
|
||||||
return Response.Success(
|
return Response.Success(
|
||||||
$"Shader '{Path.GetFileName(relativePath)}' updated successfully.",
|
$"Shader '{Path.GetFileName(relativePath)}' updated successfully.",
|
||||||
new { path = relativePath }
|
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)
|
private static string GenerateDefaultShaderContent(string name)
|
||||||
{
|
{
|
||||||
return @"Shader """ + name + @"""
|
return @"Shader """ + name + @"""
|
||||||
{
|
|
||||||
Properties
|
|
||||||
{
|
|
||||||
_MainTex (""Texture"", 2D) = ""white"" {}
|
|
||||||
}
|
|
||||||
SubShader
|
|
||||||
{
|
|
||||||
Tags { ""RenderType""=""Opaque"" }
|
|
||||||
LOD 100
|
|
||||||
|
|
||||||
Pass
|
|
||||||
{
|
{
|
||||||
CGPROGRAM
|
Properties
|
||||||
#pragma vertex vert
|
|
||||||
#pragma fragment frag
|
|
||||||
#include ""UnityCG.cginc""
|
|
||||||
|
|
||||||
struct appdata
|
|
||||||
{
|
{
|
||||||
float4 vertex : POSITION;
|
_MainTex (""Texture"", 2D) = ""white"" {}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
SubShader
|
||||||
fixed4 frag (v2f i) : SV_Target
|
|
||||||
{
|
{
|
||||||
fixed4 col = tex2D(_MainTex, i.uv);
|
Tags { ""RenderType""=""Opaque"" }
|
||||||
return col;
|
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
|
}";
|
||||||
}
|
|
||||||
}
|
|
||||||
}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bcf4f1f3110494344b2af9324cf5c571
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -378,6 +378,7 @@ namespace UnityMcpBridge.Editor
|
||||||
"manage_editor" => ManageEditor.HandleCommand(paramsObject),
|
"manage_editor" => ManageEditor.HandleCommand(paramsObject),
|
||||||
"manage_gameobject" => ManageGameObject.HandleCommand(paramsObject),
|
"manage_gameobject" => ManageGameObject.HandleCommand(paramsObject),
|
||||||
"manage_asset" => ManageAsset.HandleCommand(paramsObject),
|
"manage_asset" => ManageAsset.HandleCommand(paramsObject),
|
||||||
|
"manage_shader" => ManageShader.HandleCommand(paramsObject),
|
||||||
"read_console" => ReadConsole.HandleCommand(paramsObject),
|
"read_console" => ReadConsole.HandleCommand(paramsObject),
|
||||||
"execute_menu_item" => ExecuteMenuItem.HandleCommand(paramsObject),
|
"execute_menu_item" => ExecuteMenuItem.HandleCommand(paramsObject),
|
||||||
_ => throw new ArgumentException(
|
_ => throw new ArgumentException(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue