using System; using System.Collections.Generic; using UnityEngine; namespace DunGen.Pooling { [Serializable] public sealed class TilePoolPreloaderEntry { public Tile TilePrefab = null; public int Count = 1; } /// /// This class is used to create a collection of tiles in the scene to pre-load the tile pool /// [DisallowMultipleComponent] [AddComponentMenu("DunGen/Pooling/Tile Pool Pre-loader")] public class TilePoolPreloader : MonoBehaviour { #region Nested Types [Serializable] public sealed class SpawnedTileInstances { public Tile TilePrefab; public List Instances = new List(); } #endregion public List Entries = new List(); [SerializeField] private List spawnedTileInstances = new List(); public void ClearSpawnedInstances() { foreach(var entry in spawnedTileInstances) { foreach (var instance in entry.Instances) if(instance != null) DestroyImmediate(instance.gameObject); } spawnedTileInstances.Clear(); } public IEnumerable GetTileInstancesForPrefab(Tile prefab) { if (prefab == null) return null; var entry = spawnedTileInstances.Find(x => x.TilePrefab == prefab); if (entry != null) return entry.Instances; return null; } public bool HasSpawnedInstances() => spawnedTileInstances.Count > 0; public void RefreshTileInstances() { // Remove instances for tiles we're no longer interested in for (int i = spawnedTileInstances.Count - 1; i >= 0; i--) { var entry = spawnedTileInstances[i]; bool shouldExist = entry.TilePrefab != null && Entries.Exists(x => x.TilePrefab == entry.TilePrefab); if (!shouldExist) { foreach (var instance in entry.Instances) if (instance != null) DestroyImmediate(instance.gameObject); spawnedTileInstances.RemoveAt(i); } } // Add or update instances for tiles we're interested in foreach (var entry in Entries) { if(entry.TilePrefab == null) continue; var spawnedTileInstance = spawnedTileInstances.Find(x => x.TilePrefab == entry.TilePrefab); if (spawnedTileInstance == null) { spawnedTileInstance = new SpawnedTileInstances { TilePrefab = entry.TilePrefab }; spawnedTileInstances.Add(spawnedTileInstance); } // Clear invalid instances spawnedTileInstance.Instances.RemoveAll(x => x == null); int existingCount = spawnedTileInstance.Instances.Count; // Not enough instances, create more if (existingCount < entry.Count) { int instancesToCreate = entry.Count - existingCount; for (int i = 0; i < instancesToCreate; i++) { var instance = Instantiate(entry.TilePrefab, transform); instance.gameObject.SetActive(false); spawnedTileInstance.Instances.Add(instance); } } // Too many instances, destroy the excess else if(existingCount > entry.Count) { for (int i = existingCount - 1; i >= entry.Count; i--) { var instance = spawnedTileInstance.Instances[i]; spawnedTileInstance.Instances.RemoveAt(i); if (instance != null) DestroyImmediate(instance.gameObject); } } } } } }