using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; using UnityEditor; using UnityEngine; using MCPForUnity.Editor.Helpers; namespace MCPForUnity.Editor.Tools.Vfx { internal static class ParticleWrite { public static object SetMain(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Main"); var main = ps.main; var changes = new List(); if (@params["duration"] != null) { main.duration = @params["duration"].ToObject(); changes.Add("duration"); } if (@params["looping"] != null) { main.loop = @params["looping"].ToObject(); changes.Add("looping"); } if (@params["prewarm"] != null) { main.prewarm = @params["prewarm"].ToObject(); changes.Add("prewarm"); } if (@params["startDelay"] != null) { main.startDelay = ParticleCommon.ParseMinMaxCurve(@params["startDelay"], 0f); changes.Add("startDelay"); } if (@params["startLifetime"] != null) { main.startLifetime = ParticleCommon.ParseMinMaxCurve(@params["startLifetime"], 5f); changes.Add("startLifetime"); } if (@params["startSpeed"] != null) { main.startSpeed = ParticleCommon.ParseMinMaxCurve(@params["startSpeed"], 5f); changes.Add("startSpeed"); } if (@params["startSize"] != null) { main.startSize = ParticleCommon.ParseMinMaxCurve(@params["startSize"], 1f); changes.Add("startSize"); } if (@params["startRotation"] != null) { main.startRotation = ParticleCommon.ParseMinMaxCurve(@params["startRotation"], 0f); changes.Add("startRotation"); } if (@params["startColor"] != null) { main.startColor = ParticleCommon.ParseMinMaxGradient(@params["startColor"]); changes.Add("startColor"); } if (@params["gravityModifier"] != null) { main.gravityModifier = ParticleCommon.ParseMinMaxCurve(@params["gravityModifier"], 0f); changes.Add("gravityModifier"); } if (@params["simulationSpace"] != null && Enum.TryParse(@params["simulationSpace"].ToString(), true, out var simSpace)) { main.simulationSpace = simSpace; changes.Add("simulationSpace"); } if (@params["scalingMode"] != null && Enum.TryParse(@params["scalingMode"].ToString(), true, out var scaleMode)) { main.scalingMode = scaleMode; changes.Add("scalingMode"); } if (@params["playOnAwake"] != null) { main.playOnAwake = @params["playOnAwake"].ToObject(); changes.Add("playOnAwake"); } if (@params["maxParticles"] != null) { main.maxParticles = @params["maxParticles"].ToObject(); changes.Add("maxParticles"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated: {string.Join(", ", changes)}" }; } public static object SetEmission(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Emission"); var emission = ps.emission; var changes = new List(); if (@params["enabled"] != null) { emission.enabled = @params["enabled"].ToObject(); changes.Add("enabled"); } if (@params["rateOverTime"] != null) { emission.rateOverTime = ParticleCommon.ParseMinMaxCurve(@params["rateOverTime"], 10f); changes.Add("rateOverTime"); } if (@params["rateOverDistance"] != null) { emission.rateOverDistance = ParticleCommon.ParseMinMaxCurve(@params["rateOverDistance"], 0f); changes.Add("rateOverDistance"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated emission: {string.Join(", ", changes)}" }; } public static object SetShape(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Shape"); var shape = ps.shape; var changes = new List(); if (@params["enabled"] != null) { shape.enabled = @params["enabled"].ToObject(); changes.Add("enabled"); } if (@params["shapeType"] != null && Enum.TryParse(@params["shapeType"].ToString(), true, out var shapeType)) { shape.shapeType = shapeType; changes.Add("shapeType"); } if (@params["radius"] != null) { shape.radius = @params["radius"].ToObject(); changes.Add("radius"); } if (@params["radiusThickness"] != null) { shape.radiusThickness = @params["radiusThickness"].ToObject(); changes.Add("radiusThickness"); } if (@params["angle"] != null) { shape.angle = @params["angle"].ToObject(); changes.Add("angle"); } if (@params["arc"] != null) { shape.arc = @params["arc"].ToObject(); changes.Add("arc"); } if (@params["position"] != null) { shape.position = ManageVfxCommon.ParseVector3(@params["position"]); changes.Add("position"); } if (@params["rotation"] != null) { shape.rotation = ManageVfxCommon.ParseVector3(@params["rotation"]); changes.Add("rotation"); } if (@params["scale"] != null) { shape.scale = ManageVfxCommon.ParseVector3(@params["scale"]); changes.Add("scale"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated shape: {string.Join(", ", changes)}" }; } public static object SetColorOverLifetime(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Color Over Lifetime"); var col = ps.colorOverLifetime; var changes = new List(); if (@params["enabled"] != null) { col.enabled = @params["enabled"].ToObject(); changes.Add("enabled"); } if (@params["color"] != null) { col.color = ParticleCommon.ParseMinMaxGradient(@params["color"]); changes.Add("color"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated: {string.Join(", ", changes)}" }; } public static object SetSizeOverLifetime(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Size Over Lifetime"); var sol = ps.sizeOverLifetime; var changes = new List(); bool hasSizeProperty = @params["size"] != null || @params["sizeX"] != null || @params["sizeY"] != null || @params["sizeZ"] != null; if (hasSizeProperty && @params["enabled"] == null && !sol.enabled) { sol.enabled = true; changes.Add("enabled"); } else if (@params["enabled"] != null) { sol.enabled = @params["enabled"].ToObject(); changes.Add("enabled"); } if (@params["separateAxes"] != null) { sol.separateAxes = @params["separateAxes"].ToObject(); changes.Add("separateAxes"); } if (@params["size"] != null) { sol.size = ParticleCommon.ParseMinMaxCurve(@params["size"], 1f); changes.Add("size"); } if (@params["sizeX"] != null) { sol.x = ParticleCommon.ParseMinMaxCurve(@params["sizeX"], 1f); changes.Add("sizeX"); } if (@params["sizeY"] != null) { sol.y = ParticleCommon.ParseMinMaxCurve(@params["sizeY"], 1f); changes.Add("sizeY"); } if (@params["sizeZ"] != null) { sol.z = ParticleCommon.ParseMinMaxCurve(@params["sizeZ"], 1f); changes.Add("sizeZ"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated: {string.Join(", ", changes)}" }; } public static object SetVelocityOverLifetime(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Velocity Over Lifetime"); var vol = ps.velocityOverLifetime; var changes = new List(); if (@params["enabled"] != null) { vol.enabled = @params["enabled"].ToObject(); changes.Add("enabled"); } if (@params["space"] != null && Enum.TryParse(@params["space"].ToString(), true, out var space)) { vol.space = space; changes.Add("space"); } if (@params["x"] != null) { vol.x = ParticleCommon.ParseMinMaxCurve(@params["x"], 0f); changes.Add("x"); } if (@params["y"] != null) { vol.y = ParticleCommon.ParseMinMaxCurve(@params["y"], 0f); changes.Add("y"); } if (@params["z"] != null) { vol.z = ParticleCommon.ParseMinMaxCurve(@params["z"], 0f); changes.Add("z"); } if (@params["speedModifier"] != null) { vol.speedModifier = ParticleCommon.ParseMinMaxCurve(@params["speedModifier"], 1f); changes.Add("speedModifier"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated: {string.Join(", ", changes)}" }; } public static object SetNoise(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; Undo.RecordObject(ps, "Set ParticleSystem Noise"); var noise = ps.noise; var changes = new List(); if (@params["enabled"] != null) { noise.enabled = @params["enabled"].ToObject(); changes.Add("enabled"); } if (@params["strength"] != null) { noise.strength = ParticleCommon.ParseMinMaxCurve(@params["strength"], 1f); changes.Add("strength"); } if (@params["frequency"] != null) { noise.frequency = @params["frequency"].ToObject(); changes.Add("frequency"); } if (@params["scrollSpeed"] != null) { noise.scrollSpeed = ParticleCommon.ParseMinMaxCurve(@params["scrollSpeed"], 0f); changes.Add("scrollSpeed"); } if (@params["damping"] != null) { noise.damping = @params["damping"].ToObject(); changes.Add("damping"); } if (@params["octaveCount"] != null) { noise.octaveCount = @params["octaveCount"].ToObject(); changes.Add("octaveCount"); } if (@params["quality"] != null && Enum.TryParse(@params["quality"].ToString(), true, out var quality)) { noise.quality = quality; changes.Add("quality"); } EditorUtility.SetDirty(ps); return new { success = true, message = $"Updated noise: {string.Join(", ", changes)}" }; } public static object SetRenderer(JObject @params) { ParticleSystem ps = ParticleCommon.FindParticleSystem(@params); if (ps == null) return new { success = false, message = "ParticleSystem not found" }; var renderer = ps.GetComponent(); if (renderer == null) return new { success = false, message = "ParticleSystemRenderer not found" }; Undo.RecordObject(renderer, "Set ParticleSystem Renderer"); var changes = new List(); if (@params["renderMode"] != null && Enum.TryParse(@params["renderMode"].ToString(), true, out var renderMode)) { renderer.renderMode = renderMode; changes.Add("renderMode"); } if (@params["sortMode"] != null && Enum.TryParse(@params["sortMode"].ToString(), true, out var sortMode)) { renderer.sortMode = sortMode; changes.Add("sortMode"); } if (@params["minParticleSize"] != null) { renderer.minParticleSize = @params["minParticleSize"].ToObject(); changes.Add("minParticleSize"); } if (@params["maxParticleSize"] != null) { renderer.maxParticleSize = @params["maxParticleSize"].ToObject(); changes.Add("maxParticleSize"); } if (@params["lengthScale"] != null) { renderer.lengthScale = @params["lengthScale"].ToObject(); changes.Add("lengthScale"); } if (@params["velocityScale"] != null) { renderer.velocityScale = @params["velocityScale"].ToObject(); changes.Add("velocityScale"); } if (@params["cameraVelocityScale"] != null) { renderer.cameraVelocityScale = @params["cameraVelocityScale"].ToObject(); changes.Add("cameraVelocityScale"); } if (@params["normalDirection"] != null) { renderer.normalDirection = @params["normalDirection"].ToObject(); changes.Add("normalDirection"); } if (@params["alignment"] != null && Enum.TryParse(@params["alignment"].ToString(), true, out var alignment)) { renderer.alignment = alignment; changes.Add("alignment"); } if (@params["pivot"] != null) { renderer.pivot = ManageVfxCommon.ParseVector3(@params["pivot"]); changes.Add("pivot"); } if (@params["flip"] != null) { renderer.flip = ManageVfxCommon.ParseVector3(@params["flip"]); changes.Add("flip"); } if (@params["allowRoll"] != null) { renderer.allowRoll = @params["allowRoll"].ToObject(); changes.Add("allowRoll"); } if (@params["shadowBias"] != null) { renderer.shadowBias = @params["shadowBias"].ToObject(); changes.Add("shadowBias"); } RendererHelpers.ApplyCommonRendererProperties(renderer, @params, changes); if (@params["materialPath"] != null) { var findInst = new JObject { ["find"] = @params["materialPath"].ToString() }; Material mat = ObjectResolver.Resolve(findInst, typeof(Material)) as Material; if (mat != null) { renderer.sharedMaterial = mat; changes.Add("material"); } } if (@params["trailMaterialPath"] != null) { var findInst = new JObject { ["find"] = @params["trailMaterialPath"].ToString() }; Material mat = ObjectResolver.Resolve(findInst, typeof(Material)) as Material; if (mat != null) { renderer.trailMaterial = mat; changes.Add("trailMaterial"); } } EditorUtility.SetDirty(renderer); return new { success = true, message = $"Updated renderer: {string.Join(", ", changes)}" }; } } }