commit
03c12d0f3c
|
|
@ -2,6 +2,8 @@ using UnityEngine;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using UnityEngine.Rendering.Universal;
|
using UnityEngine.Rendering.Universal;
|
||||||
using UnityEngine.Rendering;
|
using UnityEngine.Rendering;
|
||||||
|
using UnityEditor;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace MCPServer.Editor.Commands
|
namespace MCPServer.Editor.Commands
|
||||||
{
|
{
|
||||||
|
|
@ -22,26 +24,72 @@ namespace MCPServer.Editor.Commands
|
||||||
// Check if URP is being used
|
// Check if URP is being used
|
||||||
bool isURP = GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset;
|
bool isURP = GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset;
|
||||||
|
|
||||||
// Create material with appropriate shader based on render pipeline
|
Material material = null;
|
||||||
Material material;
|
string materialName = (string)@params["material_name"];
|
||||||
if (isURP)
|
bool createIfMissing = (bool)(@params["create_if_missing"] ?? true);
|
||||||
|
string materialPath = null;
|
||||||
|
|
||||||
|
// If material name is specified, try to find or create it
|
||||||
|
if (!string.IsNullOrEmpty(materialName))
|
||||||
{
|
{
|
||||||
material = new Material(Shader.Find("Universal Render Pipeline/Lit"));
|
// Ensure Materials folder exists
|
||||||
|
const string materialsFolder = "Assets/Materials";
|
||||||
|
if (!Directory.Exists(materialsFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(materialsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
materialPath = $"{materialsFolder}/{materialName}.mat";
|
||||||
|
material = AssetDatabase.LoadAssetAtPath<Material>(materialPath);
|
||||||
|
|
||||||
|
if (material == null && createIfMissing)
|
||||||
|
{
|
||||||
|
// Create new material with appropriate shader
|
||||||
|
material = new Material(isURP ? Shader.Find("Universal Render Pipeline/Lit") : Shader.Find("Standard"));
|
||||||
|
material.name = materialName;
|
||||||
|
|
||||||
|
// Save the material asset
|
||||||
|
AssetDatabase.CreateAsset(material, materialPath);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
}
|
||||||
|
else if (material == null)
|
||||||
|
{
|
||||||
|
throw new System.Exception($"Material '{materialName}' not found and create_if_missing is false.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
material = new Material(Shader.Find("Standard"));
|
// Create a temporary material if no name specified
|
||||||
|
material = new Material(isURP ? Shader.Find("Universal Render Pipeline/Lit") : Shader.Find("Standard"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (@params.ContainsKey("material_name")) material.name = (string)@params["material_name"];
|
// Apply color if specified
|
||||||
if (@params.ContainsKey("color"))
|
if (@params.ContainsKey("color"))
|
||||||
{
|
{
|
||||||
var colorArray = (JArray)@params["color"] ?? throw new System.Exception("Invalid color parameter.");
|
var colorArray = (JArray)@params["color"];
|
||||||
if (colorArray.Count != 3) throw new System.Exception("Color must be an array of 3 floats [r, g, b].");
|
if (colorArray.Count < 3 || colorArray.Count > 4)
|
||||||
material.color = new Color((float)colorArray[0], (float)colorArray[1], (float)colorArray[2]);
|
throw new System.Exception("Color must be an array of 3 (RGB) or 4 (RGBA) floats.");
|
||||||
|
|
||||||
|
Color color = new Color(
|
||||||
|
(float)colorArray[0],
|
||||||
|
(float)colorArray[1],
|
||||||
|
(float)colorArray[2],
|
||||||
|
colorArray.Count > 3 ? (float)colorArray[3] : 1.0f
|
||||||
|
);
|
||||||
|
material.color = color;
|
||||||
|
|
||||||
|
// If this is a saved material, make sure to save the color change
|
||||||
|
if (!string.IsNullOrEmpty(materialPath))
|
||||||
|
{
|
||||||
|
EditorUtility.SetDirty(material);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the material to the renderer
|
||||||
renderer.material = material;
|
renderer.material = material;
|
||||||
return new { material_name = material.name };
|
|
||||||
|
return new { material_name = material.name, path = materialPath };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from mcp.server.fastmcp import FastMCP, Context
|
from mcp.server.fastmcp import FastMCP, Context
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
from unity_connection import get_unity_connection
|
from unity_connection import get_unity_connection
|
||||||
|
|
||||||
def register_material_tools(mcp: FastMCP):
|
def register_material_tools(mcp: FastMCP):
|
||||||
|
|
@ -9,18 +9,22 @@ def register_material_tools(mcp: FastMCP):
|
||||||
def set_material(
|
def set_material(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
object_name: str,
|
object_name: str,
|
||||||
material_name: str = None,
|
material_name: Optional[str] = None,
|
||||||
color: List[float] = None,
|
color: Optional[List[float]] = None,
|
||||||
create_if_missing: bool = True
|
create_if_missing: bool = True
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Apply or create a material for a game object.
|
Apply or create a material for a game object. If material_name is provided,
|
||||||
|
the material will be saved as a shared asset in the Materials folder.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
object_name: Target game object.
|
object_name: Target game object.
|
||||||
material_name: Optional material name.
|
material_name: Optional material name. If provided, creates/uses a shared material asset.
|
||||||
color: Optional [R, G, B] values (0.0-1.0).
|
color: Optional [R, G, B] or [R, G, B, A] values (0.0-1.0).
|
||||||
create_if_missing: Whether to create the material if it doesn't exist (default: True).
|
create_if_missing: Whether to create the material if it doesn't exist (default: True).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Status message indicating success or failure.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
unity = get_unity_connection()
|
unity = get_unity_connection()
|
||||||
|
|
@ -63,14 +67,23 @@ def register_material_tools(mcp: FastMCP):
|
||||||
return f"Error: Color {channel} value must be in the range 0.0-1.0, but got {value}."
|
return f"Error: Color {channel} value must be in the range 0.0-1.0, but got {value}."
|
||||||
|
|
||||||
# Set up parameters for the command
|
# Set up parameters for the command
|
||||||
params = {"object_name": object_name}
|
params = {
|
||||||
|
"object_name": object_name,
|
||||||
|
"create_if_missing": create_if_missing
|
||||||
|
}
|
||||||
if material_name:
|
if material_name:
|
||||||
params["material_name"] = material_name
|
params["material_name"] = material_name
|
||||||
params["create_if_missing"] = create_if_missing
|
|
||||||
if color:
|
if color:
|
||||||
params["color"] = color
|
params["color"] = color
|
||||||
|
|
||||||
result = unity.send_command("SET_MATERIAL", params)
|
result = unity.send_command("SET_MATERIAL", params)
|
||||||
return f"Applied material to {object_name}: {result.get('material_name', 'unknown')}"
|
material_name = result.get("material_name", "unknown")
|
||||||
|
material_path = result.get("path")
|
||||||
|
|
||||||
|
if material_path:
|
||||||
|
return f"Applied shared material '{material_name}' to {object_name} (saved at {material_path})"
|
||||||
|
else:
|
||||||
|
return f"Applied instance material '{material_name}' to {object_name}"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"Error setting material: {str(e)}"
|
return f"Error setting material: {str(e)}"
|
||||||
Loading…
Reference in New Issue