using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEditor; namespace MCPForUnity.Editor.Helpers { /// /// Utility class for common Renderer property operations. /// Used by ManageVFX for ParticleSystem, LineRenderer, and TrailRenderer components. /// public static class RendererHelpers { /// /// Applies common Renderer properties (shadows, lighting, probes, sorting, rendering layer). /// Used by ParticleSetRenderer, LineSetProperties, TrailSetProperties. /// public static void ApplyCommonRendererProperties(Renderer renderer, JObject @params, List changes) { // Shadows if (@params["shadowCastingMode"] != null && Enum.TryParse(@params["shadowCastingMode"].ToString(), true, out var shadowMode)) { renderer.shadowCastingMode = shadowMode; changes.Add("shadowCastingMode"); } if (@params["receiveShadows"] != null) { renderer.receiveShadows = @params["receiveShadows"].ToObject(); changes.Add("receiveShadows"); } // Note: shadowBias is only available on specific renderer types (e.g., ParticleSystemRenderer), not base Renderer // Lighting and probes if (@params["lightProbeUsage"] != null && Enum.TryParse(@params["lightProbeUsage"].ToString(), true, out var probeUsage)) { renderer.lightProbeUsage = probeUsage; changes.Add("lightProbeUsage"); } if (@params["reflectionProbeUsage"] != null && Enum.TryParse(@params["reflectionProbeUsage"].ToString(), true, out var reflectionUsage)) { renderer.reflectionProbeUsage = reflectionUsage; changes.Add("reflectionProbeUsage"); } // Motion vectors if (@params["motionVectorGenerationMode"] != null && Enum.TryParse(@params["motionVectorGenerationMode"].ToString(), true, out var motionMode)) { renderer.motionVectorGenerationMode = motionMode; changes.Add("motionVectorGenerationMode"); } // Sorting if (@params["sortingOrder"] != null) { renderer.sortingOrder = @params["sortingOrder"].ToObject(); changes.Add("sortingOrder"); } if (@params["sortingLayerName"] != null) { renderer.sortingLayerName = @params["sortingLayerName"].ToString(); changes.Add("sortingLayerName"); } if (@params["sortingLayerID"] != null) { renderer.sortingLayerID = @params["sortingLayerID"].ToObject(); changes.Add("sortingLayerID"); } // Rendering layer mask (for SRP) if (@params["renderingLayerMask"] != null) { renderer.renderingLayerMask = @params["renderingLayerMask"].ToObject(); changes.Add("renderingLayerMask"); } } /// /// Gets common Renderer properties for GetInfo methods. /// public static object GetCommonRendererInfo(Renderer renderer) { return new { shadowCastingMode = renderer.shadowCastingMode.ToString(), receiveShadows = renderer.receiveShadows, lightProbeUsage = renderer.lightProbeUsage.ToString(), reflectionProbeUsage = renderer.reflectionProbeUsage.ToString(), sortingOrder = renderer.sortingOrder, sortingLayerName = renderer.sortingLayerName, renderingLayerMask = renderer.renderingLayerMask }; } /// /// Sets width properties for LineRenderer or TrailRenderer. /// /// JSON parameters containing width, startWidth, endWidth, widthCurve, widthMultiplier /// List to track changed properties /// Action to set start width /// Action to set end width /// Action to set width curve /// Action to set width multiplier /// Function to parse animation curve from JToken public static void ApplyWidthProperties(JObject @params, List changes, Action setStartWidth, Action setEndWidth, Action setWidthCurve, Action setWidthMultiplier, Func parseAnimationCurve) { if (@params["width"] != null) { float w = @params["width"].ToObject(); setStartWidth(w); setEndWidth(w); changes.Add("width"); } if (@params["startWidth"] != null) { setStartWidth(@params["startWidth"].ToObject()); changes.Add("startWidth"); } if (@params["endWidth"] != null) { setEndWidth(@params["endWidth"].ToObject()); changes.Add("endWidth"); } if (@params["widthCurve"] != null) { setWidthCurve(parseAnimationCurve(@params["widthCurve"], 1f)); changes.Add("widthCurve"); } if (@params["widthMultiplier"] != null) { setWidthMultiplier(@params["widthMultiplier"].ToObject()); changes.Add("widthMultiplier"); } } /// /// Sets color properties for LineRenderer or TrailRenderer. /// /// JSON parameters containing color, startColor, endColor, gradient /// List to track changed properties /// Action to set start color /// Action to set end color /// Action to set gradient /// Function to parse color from JToken /// Function to parse gradient from JToken /// If true, sets end color alpha to 0 when using single color public static void ApplyColorProperties(JObject @params, List changes, Action setStartColor, Action setEndColor, Action setGradient, Func parseColor, Func parseGradient, bool fadeEndAlpha = false) { if (@params["color"] != null) { Color c = parseColor(@params["color"]); setStartColor(c); setEndColor(fadeEndAlpha ? new Color(c.r, c.g, c.b, 0f) : c); changes.Add("color"); } if (@params["startColor"] != null) { setStartColor(parseColor(@params["startColor"])); changes.Add("startColor"); } if (@params["endColor"] != null) { setEndColor(parseColor(@params["endColor"])); changes.Add("endColor"); } if (@params["gradient"] != null) { setGradient(parseGradient(@params["gradient"])); changes.Add("gradient"); } } /// /// Sets material for a Renderer. /// /// The renderer to set material on /// JSON parameters containing materialPath /// Name for the undo operation /// Function to find material by path public static object SetRendererMaterial(Renderer renderer, JObject @params, string undoName, Func findMaterial) { if (renderer == null) return new { success = false, message = "Renderer not found" }; string path = @params["materialPath"]?.ToString(); if (string.IsNullOrEmpty(path)) return new { success = false, message = "materialPath required" }; Material mat = findMaterial(path); if (mat == null) return new { success = false, message = $"Material not found: {path}" }; Undo.RecordObject(renderer, undoName); renderer.sharedMaterial = mat; EditorUtility.SetDirty(renderer); return new { success = true, message = $"Set material to {mat.name}" }; } /// /// Applies Line/Trail specific properties (loop, alignment, textureMode, etc.). /// public static void ApplyLineTrailProperties(JObject @params, List changes, Action setLoop, Action setUseWorldSpace, Action setNumCornerVertices, Action setNumCapVertices, Action setAlignment, Action setTextureMode, Action setGenerateLightingData) { if (@params["loop"] != null && setLoop != null) { setLoop(@params["loop"].ToObject()); changes.Add("loop"); } if (@params["useWorldSpace"] != null && setUseWorldSpace != null) { setUseWorldSpace(@params["useWorldSpace"].ToObject()); changes.Add("useWorldSpace"); } if (@params["numCornerVertices"] != null && setNumCornerVertices != null) { setNumCornerVertices(@params["numCornerVertices"].ToObject()); changes.Add("numCornerVertices"); } if (@params["numCapVertices"] != null && setNumCapVertices != null) { setNumCapVertices(@params["numCapVertices"].ToObject()); changes.Add("numCapVertices"); } if (@params["alignment"] != null && setAlignment != null && Enum.TryParse(@params["alignment"].ToString(), true, out var align)) { setAlignment(align); changes.Add("alignment"); } if (@params["textureMode"] != null && setTextureMode != null && Enum.TryParse(@params["textureMode"].ToString(), true, out var texMode)) { setTextureMode(texMode); changes.Add("textureMode"); } if (@params["generateLightingData"] != null && setGenerateLightingData != null) { setGenerateLightingData(@params["generateLightingData"].ToObject()); changes.Add("generateLightingData"); } } } }