Skip to main content
Glama
MaterialParameterToolTests.cs7.3 kB
using System; using System.IO; using Newtonsoft.Json.Linq; using NUnit.Framework; using UnityEditor; using UnityEngine; using MCPForUnity.Editor.Tools; namespace MCPForUnityTests.Editor.Tools { public class MaterialParameterToolTests { private const string TempRoot = "Assets/Temp/MaterialParameterToolTests"; private string _matPath; // unique per test run private GameObject _sphere; [SetUp] public void SetUp() { _matPath = $"{TempRoot}/BlueURP_{Guid.NewGuid().ToString("N")}.mat"; if (!AssetDatabase.IsValidFolder("Assets/Temp")) { AssetDatabase.CreateFolder("Assets", "Temp"); } if (!AssetDatabase.IsValidFolder(TempRoot)) { AssetDatabase.CreateFolder("Assets/Temp", "MaterialParameterToolTests"); } // Ensure any leftover material from previous runs is removed if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_matPath) != null) { AssetDatabase.DeleteAsset(_matPath); AssetDatabase.Refresh(); } // Hard-delete any stray files on disk (in case GUID lookup fails) var abs = Path.Combine(Directory.GetCurrentDirectory(), _matPath); try { if (File.Exists(abs)) File.Delete(abs); if (File.Exists(abs + ".meta")) File.Delete(abs + ".meta"); } catch { /* best-effort cleanup */ } AssetDatabase.Refresh(); } [TearDown] public void TearDown() { if (_sphere != null) { UnityEngine.Object.DestroyImmediate(_sphere); _sphere = null; } if (AssetDatabase.LoadAssetAtPath<Material>(_matPath) != null) { AssetDatabase.DeleteAsset(_matPath); } // Clean up temp directory after each test if (AssetDatabase.IsValidFolder(TempRoot)) { AssetDatabase.DeleteAsset(TempRoot); } // Clean up parent Temp folder if it's empty if (AssetDatabase.IsValidFolder("Assets/Temp")) { var remainingDirs = Directory.GetDirectories("Assets/Temp"); var remainingFiles = Directory.GetFiles("Assets/Temp"); if (remainingDirs.Length == 0 && remainingFiles.Length == 0) { AssetDatabase.DeleteAsset("Assets/Temp"); } } AssetDatabase.Refresh(); } private static JObject ToJObject(object result) { return result as JObject ?? JObject.FromObject(result); } [Test] public void CreateMaterial_WithObjectProperties_SucceedsAndSetsColor() { // Ensure a clean state if a previous run left the asset behind (uses _matPath now) if (AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(_matPath) != null) { AssetDatabase.DeleteAsset(_matPath); AssetDatabase.Refresh(); } var createParams = new JObject { ["action"] = "create", ["path"] = _matPath, ["assetType"] = "Material", ["properties"] = new JObject { ["shader"] = "Universal Render Pipeline/Lit", ["color"] = new JArray(0f, 0f, 1f, 1f) } }; var result = ToJObject(ManageAsset.HandleCommand(createParams)); Assert.IsTrue(result.Value<bool>("success"), result.Value<string>("error")); var mat = AssetDatabase.LoadAssetAtPath<Material>(_matPath); Assert.IsNotNull(mat, "Material should exist at path."); // Verify color if shader exposes _Color if (mat.HasProperty("_Color")) { Assert.AreEqual(Color.blue, mat.GetColor("_Color")); } } [Test] public void AssignMaterial_ToSphere_UsingComponentPropertiesObject_Succeeds() { // Ensure material exists first CreateMaterial_WithObjectProperties_SucceedsAndSetsColor(); // Create a sphere via handler var createGo = new JObject { ["action"] = "create", ["name"] = "ToolTestSphere", ["primitiveType"] = "Sphere" }; var createGoResult = ToJObject(ManageGameObject.HandleCommand(createGo)); Assert.IsTrue(createGoResult.Value<bool>("success"), createGoResult.Value<string>("error")); _sphere = GameObject.Find("ToolTestSphere"); Assert.IsNotNull(_sphere, "Sphere should be created."); // Assign material via object-typed componentProperties var modifyParams = new JObject { ["action"] = "modify", ["target"] = "ToolTestSphere", ["searchMethod"] = "by_name", ["componentProperties"] = new JObject { ["MeshRenderer"] = new JObject { ["sharedMaterial"] = _matPath } } }; var modifyResult = ToJObject(ManageGameObject.HandleCommand(modifyParams)); Assert.IsTrue(modifyResult.Value<bool>("success"), modifyResult.Value<string>("error")); var renderer = _sphere.GetComponent<MeshRenderer>(); Assert.IsNotNull(renderer, "Sphere should have MeshRenderer."); Assert.IsNotNull(renderer.sharedMaterial, "sharedMaterial should be assigned."); StringAssert.StartsWith("BlueURP_", renderer.sharedMaterial.name); } [Test] public void ReadRendererData_DoesNotInstantiateMaterial_AndIncludesSharedMaterial() { // Prepare object and assignment AssignMaterial_ToSphere_UsingComponentPropertiesObject_Succeeds(); var renderer = _sphere.GetComponent<MeshRenderer>(); int beforeId = renderer.sharedMaterial != null ? renderer.sharedMaterial.GetInstanceID() : 0; var data = MCPForUnity.Editor.Helpers.GameObjectSerializer.GetComponentData(renderer) as System.Collections.Generic.Dictionary<string, object>; Assert.IsNotNull(data, "Serializer should return data."); int afterId = renderer.sharedMaterial != null ? renderer.sharedMaterial.GetInstanceID() : 0; Assert.AreEqual(beforeId, afterId, "sharedMaterial instance must not change (no instantiation in EditMode)."); if (data.TryGetValue("properties", out var propsObj) && propsObj is System.Collections.Generic.Dictionary<string, object> props) { Assert.IsTrue( props.ContainsKey("sharedMaterial") || props.ContainsKey("material") || props.ContainsKey("sharedMaterials") || props.ContainsKey("materials"), "Serialized data should include material info."); } } } }

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