TilePoolPreloader.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace DunGen.Pooling
  5. {
  6. [Serializable]
  7. public sealed class TilePoolPreloaderEntry
  8. {
  9. public Tile TilePrefab = null;
  10. public int Count = 1;
  11. }
  12. /// <summary>
  13. /// This class is used to create a collection of tiles in the scene to pre-load the tile pool
  14. /// </summary>
  15. [DisallowMultipleComponent]
  16. [AddComponentMenu("DunGen/Pooling/Tile Pool Pre-loader")]
  17. public class TilePoolPreloader : MonoBehaviour
  18. {
  19. #region Nested Types
  20. [Serializable]
  21. public sealed class SpawnedTileInstances
  22. {
  23. public Tile TilePrefab;
  24. public List<Tile> Instances = new List<Tile>();
  25. }
  26. #endregion
  27. public List<TilePoolPreloaderEntry> Entries = new List<TilePoolPreloaderEntry>();
  28. [SerializeField]
  29. private List<SpawnedTileInstances> spawnedTileInstances = new List<SpawnedTileInstances>();
  30. public void ClearSpawnedInstances()
  31. {
  32. foreach(var entry in spawnedTileInstances)
  33. {
  34. foreach (var instance in entry.Instances)
  35. if(instance != null)
  36. DestroyImmediate(instance.gameObject);
  37. }
  38. spawnedTileInstances.Clear();
  39. }
  40. public IEnumerable<Tile> GetTileInstancesForPrefab(Tile prefab)
  41. {
  42. if (prefab == null)
  43. return null;
  44. var entry = spawnedTileInstances.Find(x => x.TilePrefab == prefab);
  45. if (entry != null)
  46. return entry.Instances;
  47. return null;
  48. }
  49. public bool HasSpawnedInstances() => spawnedTileInstances.Count > 0;
  50. public void RefreshTileInstances()
  51. {
  52. // Remove instances for tiles we're no longer interested in
  53. for (int i = spawnedTileInstances.Count - 1; i >= 0; i--)
  54. {
  55. var entry = spawnedTileInstances[i];
  56. bool shouldExist = entry.TilePrefab != null && Entries.Exists(x => x.TilePrefab == entry.TilePrefab);
  57. if (!shouldExist)
  58. {
  59. foreach (var instance in entry.Instances)
  60. if (instance != null)
  61. DestroyImmediate(instance.gameObject);
  62. spawnedTileInstances.RemoveAt(i);
  63. }
  64. }
  65. // Add or update instances for tiles we're interested in
  66. foreach (var entry in Entries)
  67. {
  68. if(entry.TilePrefab == null)
  69. continue;
  70. var spawnedTileInstance = spawnedTileInstances.Find(x => x.TilePrefab == entry.TilePrefab);
  71. if (spawnedTileInstance == null)
  72. {
  73. spawnedTileInstance = new SpawnedTileInstances { TilePrefab = entry.TilePrefab };
  74. spawnedTileInstances.Add(spawnedTileInstance);
  75. }
  76. // Clear invalid instances
  77. spawnedTileInstance.Instances.RemoveAll(x => x == null);
  78. int existingCount = spawnedTileInstance.Instances.Count;
  79. // Not enough instances, create more
  80. if (existingCount < entry.Count)
  81. {
  82. int instancesToCreate = entry.Count - existingCount;
  83. for (int i = 0; i < instancesToCreate; i++)
  84. {
  85. var instance = Instantiate(entry.TilePrefab, transform);
  86. instance.gameObject.SetActive(false);
  87. spawnedTileInstance.Instances.Add(instance);
  88. }
  89. }
  90. // Too many instances, destroy the excess
  91. else if(existingCount > entry.Count)
  92. {
  93. for (int i = existingCount - 1; i >= entry.Count; i--)
  94. {
  95. var instance = spawnedTileInstance.Instances[i];
  96. spawnedTileInstance.Instances.RemoveAt(i);
  97. if (instance != null)
  98. DestroyImmediate(instance.gameObject);
  99. }
  100. }
  101. }
  102. }
  103. }
  104. }