using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; namespace Beyond { public class EnemySpawnerManager : MonoBehaviour { [Header("Spawner Configurations")] [Tooltip("List of spawners to manage and their override settings.")] public List spawnerConfigurations = new List(); [Header("Global Settings (Optional)")] [Tooltip("If assigned, this prefab will be used for ALL spawners in the list that don't have their own overridePrefab set.")] public GameObject globalOverridePrefab; [Tooltip("If > 0, this will be used for ALL spawners that don't have overrideEnemiesPerWave set. Set to 0 or less to ignore.")] public int globalOverrideEnemiesPerWave = -1; public bool overrideOnStart = true; public bool autoEnableSpawners = true; public bool disableSpawnersOnStart = true; void Awake() { if (disableSpawnersOnStart) { // Disable all spawners initially if needed foreach (var config in spawnerConfigurations) { if (config.spawner != null) { config.spawner.enabled = false; } } } ApplySpawnerConfigurations(); } // You could also call this from Start() if you want to ensure all other Awakes have run, // though for setting properties on other components, Awake() is generally fine. // void Start() // { // ApplySpawnerConfigurations(); // } [Button] public void ApplySpawnerConfigurations() { if (spawnerConfigurations == null || spawnerConfigurations.Count == 0) { Debug.LogWarning("EnemySpawnerManager: No spawner configurations assigned.", this); return; } foreach (SpawnerOverrideConfig config in spawnerConfigurations) { if (config == null || config.spawner == null) { Debug.LogWarning("EnemySpawnerManager: A spawner configuration or its target spawner is null. Skipping.", this); continue; } EnemySpawner targetSpawner = config.spawner; // Apply specific override prefab if set if (config.overridePrefab != null) { targetSpawner.m_prefab = config.overridePrefab; // Debug.Log($"Manager overriding prefab for {targetSpawner.name} to {config.overridePrefab.name}", this); } // Else, if a global override prefab is set, apply that else if (globalOverridePrefab != null) { targetSpawner.m_prefab = globalOverridePrefab; // Debug.Log($"Manager applying global override prefab to {targetSpawner.name} ({globalOverridePrefab.name})", this); } // If neither specific nor global override is set, the spawner uses its own m_prefab. // Apply specific override for enemies per wave if set (and > 0) if (config.overrideEnemiesPerWave > -1) { targetSpawner.m_enemiesPerSpawnWave = config.overrideEnemiesPerWave; // Debug.Log($"Manager overriding enemies per wave for {targetSpawner.name} to {config.overrideEnemiesPerWave}", this); } // Else, if a global override for enemies per wave is set (and > 0), apply that else if (globalOverrideEnemiesPerWave > -1) { targetSpawner.m_enemiesPerSpawnWave = globalOverrideEnemiesPerWave; // Debug.Log($"Manager applying global override enemies per wave to {targetSpawner.name} ({globalOverrideEnemiesPerWave})", this); } if (autoEnableSpawners) { targetSpawner.enabled = true; // Enable the spawner if it was disabled } // If neither specific nor global override is set, the spawner uses its own m_enemiesPerSpawnWave. // --- IMPORTANT --- // Ensure the spawner hasn't already started its InvokeRepeating for CheckSpawn // if its settings are being changed. // One way is to disable the spawner initially and let the manager enable it. // Or, if spawners might already be active, you might need to CancelInvoke and Restart it. // For simplicity, let's assume spawners are either configured to not auto-start // or this manager runs early enough (e.g., via Script Execution Order). // If you want to ensure spawners don't start before manager configures them: // Option A: Set spawners to be disabled by default in the editor, then enable them here. // targetSpawner.enabled = true; // If they were disabled by default // Option B: Make sure EnemySpawnerManager's Awake runs before EnemySpawner's Start. // You can do this via Edit > Project Settings > Script Execution Order. // Add EnemySpawnerManager and set it to an earlier value (e.g., -100) // than the default time or EnemySpawner. } Debug.Log("EnemySpawnerManager: Applied configurations to spawners.", this); } // Optional: Helper to add spawners programmatically if needed public void AddSpawnerToManage(EnemySpawner spawner, GameObject prefabOverride = null, int enemiesPerWaveOverride = 0) { if (spawner == null) return; SpawnerOverrideConfig newConfig = new SpawnerOverrideConfig { spawner = spawner, overridePrefab = prefabOverride, overrideEnemiesPerWave = enemiesPerWaveOverride }; spawnerConfigurations.Add(newConfig); } /// /// Resets all managed spawners to their initial state. /// This will destroy their current enemies and restart their spawning cycles. /// [ContextMenu("Reset All Managed Spawners")] // Adds a right-click option in Inspector for easy testing [Button] public void ResetAllManagedSpawners() { if (spawnerConfigurations == null || spawnerConfigurations.Count == 0) { Debug.LogWarning("EnemySpawnerManager: No spawners configured to reset.", this); return; } Debug.Log("EnemySpawnerManager: Initiating reset for all managed spawners...", this); int resetCount = 0; foreach (SpawnerOverrideConfig config in spawnerConfigurations) { if (config != null && config.spawner != null) { config.spawner.ResetSpawner(); // Call the spawner's own reset method resetCount++; } } Debug.Log($"EnemySpawnerManager: Reset command sent to {resetCount} spawners.", this); } } }