diff --git a/UnityMcpBridge/Editor/Tools/ManageAsset.cs b/UnityMcpBridge/Editor/Tools/ManageAsset.cs index 723ef52..59f31e7 100644 --- a/UnityMcpBridge/Editor/Tools/ManageAsset.cs +++ b/UnityMcpBridge/Editor/Tools/ManageAsset.cs @@ -179,8 +179,18 @@ namespace MCPForUnity.Editor.Tools } else if (lowerAssetType == "material") { - Material mat = new Material(Shader.Find("Standard")); // Default shader - // TODO: Apply properties from JObject (e.g., shader name, color, texture assignments) + // Prefer provided shader; fall back to common pipelines + var requested = properties?["shader"]?.ToString(); + Shader shader = + (!string.IsNullOrEmpty(requested) ? Shader.Find(requested) : null) + ?? Shader.Find("Universal Render Pipeline/Lit") + ?? Shader.Find("HDRP/Lit") + ?? Shader.Find("Standard") + ?? Shader.Find("Unlit/Color"); + if (shader == null) + return Response.Error($"Could not find a suitable shader (requested: '{requested ?? "none"}')."); + + var mat = new Material(shader); if (properties != null) ApplyMaterialProperties(mat, properties); AssetDatabase.CreateAsset(mat, fullPath); @@ -1261,24 +1271,29 @@ namespace MCPForUnity.Editor.Tools { // Ensure texture is readable for EncodeToPNG // Creating a temporary readable copy is safer - RenderTexture rt = RenderTexture.GetTemporary( - preview.width, - preview.height - ); - Graphics.Blit(preview, rt); + RenderTexture rt = null; + Texture2D readablePreview = null; RenderTexture previous = RenderTexture.active; - RenderTexture.active = rt; - Texture2D readablePreview = new Texture2D(preview.width, preview.height); - readablePreview.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); - readablePreview.Apply(); - RenderTexture.active = previous; - RenderTexture.ReleaseTemporary(rt); + try + { + rt = RenderTexture.GetTemporary(preview.width, preview.height); + Graphics.Blit(preview, rt); + RenderTexture.active = rt; + readablePreview = new Texture2D(preview.width, preview.height); + readablePreview.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0); + readablePreview.Apply(); + } + finally + { + RenderTexture.active = previous; + if (rt != null) RenderTexture.ReleaseTemporary(rt); + } - byte[] pngData = readablePreview.EncodeToPNG(); + var pngData = readablePreview.EncodeToPNG(); previewBase64 = Convert.ToBase64String(pngData); previewWidth = readablePreview.width; previewHeight = readablePreview.height; - UnityEngine.Object.DestroyImmediate(readablePreview); // Clean up temp texture + UnityEngine.Object.DestroyImmediate(readablePreview); } catch (Exception ex) { diff --git a/UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py b/UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py index f29eb6b..5101670 100644 --- a/UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py +++ b/UnityMcpBridge/UnityMcpServer~/src/tools/manage_script_edits.py @@ -630,8 +630,8 @@ def register_manage_script_edits_tools(mcp: FastMCP): if not m: continue # Expand $1, $2... in replacement using this match - def _expand_dollars(rep: str) -> str: - return _re.sub(r"\$(\d+)", lambda g: m.group(int(g.group(1))) or "", rep) + def _expand_dollars(rep: str, _m=m) -> str: + return _re.sub(r"\$(\d+)", lambda g: _m.group(int(g.group(1))) or "", rep) repl = _expand_dollars(text_field) sl, sc = line_col_from_index(m.start()) el, ec = line_col_from_index(m.end()) @@ -767,8 +767,8 @@ def register_manage_script_edits_tools(mcp: FastMCP): if not m: continue # Expand $1, $2... backrefs in replacement using the first match (consistent with mixed-path behavior) - def _expand_dollars(rep: str) -> str: - return _re.sub(r"\$(\d+)", lambda g: m.group(int(g.group(1))) or "", rep) + def _expand_dollars(rep: str, _m=m) -> str: + return _re.sub(r"\$(\d+)", lambda g: _m.group(int(g.group(1))) or "", rep) repl_expanded = _expand_dollars(repl) # Let C# side handle validation using Unity's built-in compiler services sl, sc = line_col_from_index(m.start())