unity-mcp/Editor/Commands/MaterialCommandHandler.cs

95 lines
3.8 KiB
C#
Raw Normal View History

2025-03-18 19:00:50 +08:00
using UnityEngine;
using Newtonsoft.Json.Linq;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering;
2025-03-20 06:10:34 +08:00
using UnityEditor;
using System.IO;
2025-03-18 19:00:50 +08:00
2025-03-20 19:24:31 +08:00
namespace UnityMCP.Editor.Commands
2025-03-18 19:00:50 +08:00
{
/// <summary>
/// Handles material-related commands
/// </summary>
public static class MaterialCommandHandler
{
/// <summary>
/// Sets or modifies a material on an object
/// </summary>
public static object SetMaterial(JObject @params)
{
string objectName = (string)@params["object_name"] ?? throw new System.Exception("Parameter 'object_name' is required.");
var obj = GameObject.Find(objectName) ?? throw new System.Exception($"Object '{objectName}' not found.");
var renderer = obj.GetComponent<Renderer>() ?? throw new System.Exception($"Object '{objectName}' has no renderer.");
// Check if URP is being used
bool isURP = GraphicsSettings.currentRenderPipeline is UniversalRenderPipelineAsset;
2025-03-20 06:10:34 +08:00
Material material = null;
string materialName = (string)@params["material_name"];
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))
2025-03-18 19:00:50 +08:00
{
2025-03-20 06:10:34 +08:00
// 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.");
}
2025-03-18 19:00:50 +08:00
}
else
{
2025-03-20 06:10:34 +08:00
// Create a temporary material if no name specified
material = new Material(isURP ? Shader.Find("Universal Render Pipeline/Lit") : Shader.Find("Standard"));
2025-03-18 19:00:50 +08:00
}
2025-03-20 06:10:34 +08:00
// Apply color if specified
2025-03-18 19:00:50 +08:00
if (@params.ContainsKey("color"))
{
2025-03-20 06:10:34 +08:00
var colorArray = (JArray)@params["color"];
if (colorArray.Count < 3 || colorArray.Count > 4)
throw new System.Exception("Color must be an array of 3 (RGB) or 4 (RGBA) floats.");
2025-03-20 19:24:31 +08:00
Color color = new(
2025-03-20 06:10:34 +08:00
(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();
}
2025-03-18 19:00:50 +08:00
}
2025-03-20 06:10:34 +08:00
// Apply the material to the renderer
2025-03-18 19:00:50 +08:00
renderer.material = material;
2025-03-20 06:10:34 +08:00
return new { material_name = material.name, path = materialPath };
2025-03-18 19:00:50 +08:00
}
}
}