Skip to main content
Glama
ManageMaterialTests.cs8.56 kB
using System; using System.IO; using Newtonsoft.Json.Linq; using NUnit.Framework; using UnityEditor; using UnityEngine; using MCPForUnity.Editor.Tools; using MCPForUnity.Editor.Helpers; namespace MCPForUnityTests.Editor.Tools { public class ManageMaterialTests { private const string TempRoot = "Assets/Temp/ManageMaterialTests"; private string _matPath; [SetUp] public void SetUp() { if (!AssetDatabase.IsValidFolder("Assets/Temp")) { AssetDatabase.CreateFolder("Assets", "Temp"); } if (!AssetDatabase.IsValidFolder(TempRoot)) { AssetDatabase.CreateFolder("Assets/Temp", "ManageMaterialTests"); } string guid = Guid.NewGuid().ToString("N"); _matPath = $"{TempRoot}/TestMat_{guid}.mat"; // Create a basic material var material = new Material(Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard")); AssetDatabase.CreateAsset(material, _matPath); AssetDatabase.SaveAssets(); } [TearDown] public void TearDown() { if (AssetDatabase.IsValidFolder(TempRoot)) { AssetDatabase.DeleteAsset(TempRoot); } // Clean up parent Temp folder if it's empty if (AssetDatabase.IsValidFolder("Assets/Temp")) { // Only delete if empty var subFolders = AssetDatabase.GetSubFolders("Assets/Temp"); if (subFolders.Length == 0) { AssetDatabase.DeleteAsset("Assets/Temp"); } } } private static JObject ToJObject(object result) { return result as JObject ?? JObject.FromObject(result); } [Test] public void SetMaterialShaderProperty_SetsColor() { // Arrange var color = new Color(1f, 1f, 0f, 1f); // Yellow var paramsObj = new JObject { ["action"] = "set_material_shader_property", ["materialPath"] = _matPath, ["property"] = "_BaseColor", // URP ["value"] = new JArray(color.r, color.g, color.b, color.a) }; // Check if using Standard shader (fallback) var mat = AssetDatabase.LoadAssetAtPath<Material>(_matPath); if (mat.shader.name == "Standard") { paramsObj["property"] = "_Color"; } // Act var result = ToJObject(ManageMaterial.HandleCommand(paramsObj)); // Assert Assert.AreEqual("success", result.Value<string>("status"), result.ToString()); mat = AssetDatabase.LoadAssetAtPath<Material>(_matPath); // Reload var prop = mat.shader.name == "Standard" ? "_Color" : "_BaseColor"; Assert.IsTrue(mat.HasProperty(prop), $"Material should have property {prop}"); Assert.AreEqual(color, mat.GetColor(prop)); } [Test] public void SetMaterialColor_SetsColorWithFallback() { // Arrange var color = new Color(0f, 1f, 0f, 1f); // Green var paramsObj = new JObject { ["action"] = "set_material_color", ["materialPath"] = _matPath, ["color"] = new JArray(color.r, color.g, color.b, color.a) }; // Act var result = ToJObject(ManageMaterial.HandleCommand(paramsObj)); // Assert Assert.AreEqual("success", result.Value<string>("status"), result.ToString()); var mat = AssetDatabase.LoadAssetAtPath<Material>(_matPath); var prop = mat.HasProperty("_BaseColor") ? "_BaseColor" : "_Color"; Assert.IsTrue(mat.HasProperty(prop), $"Material should have property {prop}"); Assert.AreEqual(color, mat.GetColor(prop)); } [Test] public void AssignMaterialToRenderer_Works() { // Arrange var go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.name = "AssignTestCube"; try { var paramsObj = new JObject { ["action"] = "assign_material_to_renderer", ["target"] = "AssignTestCube", ["searchMethod"] = "by_name", ["materialPath"] = _matPath, ["slot"] = 0 }; // Act var result = ToJObject(ManageMaterial.HandleCommand(paramsObj)); // Assert Assert.AreEqual("success", result.Value<string>("status"), result.ToString()); var renderer = go.GetComponent<Renderer>(); Assert.IsNotNull(renderer.sharedMaterial); // Compare names because objects might be different instances (loaded vs scene) var matName = Path.GetFileNameWithoutExtension(_matPath); Assert.AreEqual(matName, renderer.sharedMaterial.name); } finally { UnityEngine.Object.DestroyImmediate(go); } } [Test] public void SetRendererColor_PropertyBlock_Works() { // Arrange var go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.name = "BlockTestCube"; // Assign the material first so we have something valid var mat = AssetDatabase.LoadAssetAtPath<Material>(_matPath); go.GetComponent<Renderer>().sharedMaterial = mat; try { var color = new Color(1f, 0f, 0f, 1f); // Red var paramsObj = new JObject { ["action"] = "set_renderer_color", ["target"] = "BlockTestCube", ["searchMethod"] = "by_name", ["color"] = new JArray(color.r, color.g, color.b, color.a), ["mode"] = "property_block" }; // Act var result = ToJObject(ManageMaterial.HandleCommand(paramsObj)); // Assert Assert.AreEqual("success", result.Value<string>("status"), result.ToString()); var renderer = go.GetComponent<Renderer>(); var block = new MaterialPropertyBlock(); renderer.GetPropertyBlock(block, 0); var prop = mat.HasProperty("_BaseColor") ? "_BaseColor" : "_Color"; Assert.AreEqual(color, block.GetColor(prop)); // Verify material asset didn't change (it was originally white/gray from setup?) // We didn't check original color, but property block shouldn't affect shared material // We can check that sharedMaterial color is NOT red if we set it to something else first // But assuming test isolation, we can just verify the block is set. } finally { UnityEngine.Object.DestroyImmediate(go); } } [Test] public void GetMaterialInfo_ReturnsProperties() { // Arrange var paramsObj = new JObject { ["action"] = "get_material_info", ["materialPath"] = _matPath }; // Act var result = ToJObject(ManageMaterial.HandleCommand(paramsObj)); // Assert Assert.AreEqual("success", result.Value<string>("status"), result.ToString()); Assert.IsNotNull(result["properties"]); Assert.IsInstanceOf<JArray>(result["properties"]); var props = result["properties"] as JArray; Assert.IsTrue(props.Count > 0); // Check for standard properties bool foundColor = false; foreach(var p in props) { var name = p["name"]?.ToString(); if (name == "_Color" || name == "_BaseColor") foundColor = true; } Assert.IsTrue(foundColor, "Should find color property"); } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CoplayDev/unity-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server