using UnityEngine; using UnityEngine.VFX; using UnityEditor; using UnityEditor.Events; using RR.Game2D.Entities; public static class ReplacePlatformWithSign { [MenuItem("Tools/Replace Platform with Sign")] public static string Run() { GameObject platformObj = GameObject.Find("Level/Props/Platforms/TriggeringPlatform_2"); if (platformObj == null) { platformObj = GameObject.Find("TriggeringPlatform_2"); } if (platformObj == null) { Debug.LogError("Error: TriggeringPlatform_2 not found in scene!"); return "Error: TriggeringPlatform_2 not found in scene!"; } GameObject leverObj = GameObject.Find("Level/Props/Lever"); if (leverObj == null) { leverObj = GameObject.Find("Lever"); } if (leverObj == null) { Debug.LogError("Error: Lever not found in scene!"); return "Error: Lever not found in scene!"; } Transform parentTransform = platformObj.transform.parent; Vector3 position = platformObj.transform.position; Sprite signSprite = AssetDatabase.LoadAssetAtPath("Assets/Resources/Sprites/Props/Signs/Signs_Arrow_Left.png"); if (signSprite == null) { // Try fallback OLD folder signSprite = AssetDatabase.LoadAssetAtPath("Assets/Resources/Sprites/Props/Signs/OLD/Signs_Arrow_Left.png"); } if (signSprite == null) { Debug.LogError("Error: Signs_Arrow_Left.png not found in Assets!"); return "Error: Signs_Arrow_Left.png not found in Assets!"; } // Create sign GameObject GameObject signObj = new GameObject("SignLeft"); Undo.RegisterCreatedObjectUndo(signObj, "Create SignLeft"); signObj.transform.parent = parentTransform; signObj.transform.position = position; signObj.transform.localScale = Vector3.one; // Add SpriteRenderer SpriteRenderer sr = signObj.AddComponent(); sr.sprite = signSprite; // Copy sorting layer and order from sibling or default SpriteRenderer[] allRenderers = parentTransform.parent.GetComponentsInChildren(true); if (allRenderers != null && allRenderers.Length > 0) { sr.sortingLayerID = allRenderers[0].sortingLayerID; sr.sortingLayerName = allRenderers[0].sortingLayerName; sr.sortingOrder = allRenderers[0].sortingOrder; } else { sr.sortingLayerName = "Foreground"; sr.sortingOrder = 0; } // Add ShowObjectWithVFX component ShowObjectWithVFX triggerScript = signObj.AddComponent(); // Use reflection to set private serialized fields var targetField = typeof(ShowObjectWithVFX).GetField("targetObject", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (targetField != null) { targetField.SetValue(triggerScript, signObj); } // Create Sparks ParticleSystem GameObject sparksObj = new GameObject("Sparks"); sparksObj.transform.parent = signObj.transform; sparksObj.transform.localPosition = Vector3.zero; ParticleSystem ps = sparksObj.AddComponent(); // Configure particles to look like sparks var main = ps.main; main.duration = 1.0f; main.loop = false; main.startLifetime = new ParticleSystem.MinMaxCurve(0.4f, 0.8f); main.startSpeed = new ParticleSystem.MinMaxCurve(3.0f, 6.0f); main.startSize = new ParticleSystem.MinMaxCurve(0.1f, 0.25f); main.gravityModifier = 0.9f; main.playOnAwake = false; var emission = ps.emission; emission.enabled = true; emission.rateOverTime = 0; var burst = new ParticleSystem.Burst(0.0f, 40); emission.SetBursts(new ParticleSystem.Burst[] { burst }); var shape = ps.shape; shape.enabled = true; shape.shapeType = ParticleSystemShapeType.Cone; shape.angle = 60f; shape.radius = 0.3f; var colorOverLifetime = ps.colorOverLifetime; colorOverLifetime.enabled = true; Gradient gradient = new Gradient(); gradient.SetKeys( new GradientColorKey[] { new GradientColorKey(new Color(1f, 0.9f, 0.3f), 0.0f), new GradientColorKey(new Color(1f, 0.3f, 0.0f), 1.0f) }, new GradientAlphaKey[] { new GradientAlphaKey(1.0f, 0.0f), new GradientAlphaKey(0.0f, 1.0f) } ); colorOverLifetime.color = gradient; var psr = sparksObj.GetComponent(); if (psr != null) { psr.material = AssetDatabase.GetBuiltinExtraResource("Default-Particle.mat"); } // Assign particle system to triggerScript var psField = typeof(ShowObjectWithVFX).GetField("particleSystemComponent", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (psField != null) { psField.SetValue(triggerScript, ps); } // Set up Lever activation Lever lever = leverObj.GetComponent(); if (lever != null) { var onActivateField = typeof(Lever).GetField("onActivate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); if (onActivateField != null) { UnityEngine.Events.UnityEvent onActivate = (UnityEngine.Events.UnityEvent)onActivateField.GetValue(lever); if (onActivate != null) { // Clear any old triggers pointing to platform int persistentEventCount = onActivate.GetPersistentEventCount(); for (int i = persistentEventCount - 1; i >= 0; i--) { Object target = onActivate.GetPersistentTarget(i); if (target == platformObj || (target is Component comp && comp.gameObject == platformObj)) { UnityEventTools.RemovePersistentListener(onActivate, i); } } // Bind new activation UnityEventTools.AddPersistentListener(onActivate, triggerScript.Activate); EditorUtility.SetDirty(lever); } } } // Destroy old platform object Undo.DestroyObjectImmediate(platformObj); // Mark scene dirty and save UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(signObj.scene); UnityEditor.SceneManagement.EditorSceneManager.SaveScene(signObj.scene); Debug.Log("Success! TriggeringPlatform_2 replaced with SignLeft, particle system configured, and Lever.onActivate event updated."); return "Success!"; } }