ItemSpawner.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System;
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. using System.Collections;
  5. using Random = UnityEngine.Random;
  6. namespace HQFPSWeapons
  7. {
  8. public class ItemSpawner : MonoBehaviour
  9. {
  10. [BHeader("General", true)]
  11. [SerializeField]
  12. private bool OneTimeSpawn = false;
  13. [SerializeField]
  14. private ItemSpawnSuccesion m_SpawnType = ItemSpawnSuccesion.InOrder;
  15. [SerializeField]
  16. private ItemToSpawn[] m_ItemsToSpawn = null;
  17. [SerializeField]
  18. private Vector3 m_RandomRotation = Vector3.zero;
  19. [SerializeField]
  20. private ParticleSystem m_ParticleEffects = null;
  21. [BHeader("Delays")]
  22. [SerializeField]
  23. private float m_CanSpawnDelay = 10f;
  24. [SerializeField]
  25. private float m_InitialItemSpawnDelay = 0.5f;
  26. [SerializeField]
  27. private float m_DelayBetweenItemSpawns = 0.1f;
  28. [SerializeField]
  29. private float m_ItemDestroyDelay = 15f;
  30. [BHeader("Audio")]
  31. [SerializeField]
  32. private SoundPlayer m_StartSpawnAudio = null;
  33. [SerializeField]
  34. private SoundPlayer m_EndSpawnAudio = null;
  35. private BoxCollider m_Collider;
  36. private AudioSource m_AudioSource;
  37. private int m_ItemsToSpawnCount;
  38. private float m_NextTimeCanSpawn;
  39. private bool m_CanSpawn = true;
  40. private WaitForSeconds m_TimeBetweenSpawns;
  41. public void SpawnItems(int maxSpawnCount)
  42. {
  43. if (Time.time > m_NextTimeCanSpawn && m_CanSpawn)
  44. {
  45. maxSpawnCount = Mathf.Clamp(maxSpawnCount, 0, m_ItemsToSpawn.Length);
  46. m_NextTimeCanSpawn = Time.time + m_CanSpawnDelay;
  47. List <ItemPickup> itemsToSpawn = new List<ItemPickup>();
  48. if (m_SpawnType == ItemSpawnSuccesion.InOrder)
  49. {
  50. for (int i = 0; i < m_ItemsToSpawn.Length; i++)
  51. {
  52. if (m_ItemsToSpawnCount >= maxSpawnCount)
  53. break;
  54. for (int n = 0; n < m_ItemsToSpawn[i].Amount; n++)
  55. {
  56. if (m_ItemsToSpawnCount >= maxSpawnCount)
  57. break;
  58. itemsToSpawn.Add(m_ItemsToSpawn[i].ItemPickup);
  59. m_ItemsToSpawnCount++;
  60. }
  61. }
  62. }
  63. else if (m_SpawnType == ItemSpawnSuccesion.Random)
  64. {
  65. for (int i = 0; i < maxSpawnCount; i++)
  66. {
  67. int randomIndex = Random.Range(i, m_ItemsToSpawn.Length);
  68. ItemToSpawn randomItem = m_ItemsToSpawn[randomIndex];
  69. if (m_ItemsToSpawn[i].ItemPickup != randomItem.ItemPickup)
  70. {
  71. ItemToSpawn temp = m_ItemsToSpawn[i];
  72. m_ItemsToSpawn[i] = randomItem;
  73. m_ItemsToSpawn[randomIndex] = temp;
  74. }
  75. itemsToSpawn.Add(randomItem.ItemPickup);
  76. }
  77. }
  78. StartCoroutine(C_SpawnItems(itemsToSpawn));
  79. }
  80. }
  81. private Vector3 RandomPointInBounds(Bounds bounds)
  82. {
  83. return new Vector3(
  84. Random.Range(bounds.min.x, bounds.max.x),
  85. Random.Range(bounds.min.y, bounds.max.y),
  86. Random.Range(bounds.min.z, bounds.max.z)
  87. );
  88. }
  89. private void Start()
  90. {
  91. m_Collider = GetComponent<BoxCollider>();
  92. m_AudioSource = GetComponent<AudioSource>();
  93. m_TimeBetweenSpawns = new WaitForSeconds(m_DelayBetweenItemSpawns);
  94. }
  95. private IEnumerator C_SpawnItems(List<ItemPickup> itemsToSpawn)
  96. {
  97. yield return new WaitForSeconds(m_InitialItemSpawnDelay);
  98. m_StartSpawnAudio.Play(ItemSelection.Method.RandomExcludeLast, m_AudioSource);
  99. for (int i = 0; i < itemsToSpawn.Count; i++)
  100. {
  101. if (itemsToSpawn[i] != null)
  102. {
  103. Quaternion spawnedItemRotation = Quaternion.Euler(
  104. Random.Range(-Mathf.Abs(m_RandomRotation.x), Mathf.Abs(m_RandomRotation.x)),
  105. Random.Range(-Mathf.Abs(m_RandomRotation.y), Mathf.Abs(m_RandomRotation.y)),
  106. Random.Range(-Mathf.Abs(m_RandomRotation.z), Mathf.Abs(m_RandomRotation.z))
  107. );
  108. ItemPickup item = Instantiate(itemsToSpawn[i], RandomPointInBounds(m_Collider.bounds), spawnedItemRotation);
  109. item.StartCoroutine(item.C_DelayedDestroy(m_ItemDestroyDelay));
  110. if (m_ParticleEffects != null)
  111. Instantiate(m_ParticleEffects, item.transform.position, spawnedItemRotation);
  112. yield return m_TimeBetweenSpawns;
  113. }
  114. }
  115. if (OneTimeSpawn)
  116. m_CanSpawn = false;
  117. m_ItemsToSpawnCount = 0;
  118. m_EndSpawnAudio.Play(ItemSelection.Method.RandomExcludeLast, m_AudioSource);
  119. }
  120. // ------------------- Internal ------------------
  121. [Serializable]
  122. private struct ItemToSpawn
  123. {
  124. #pragma warning disable 0649
  125. public ItemPickup ItemPickup;
  126. public int Amount;
  127. #pragma warning restore 0649
  128. }
  129. public enum ItemSpawnSuccesion
  130. {
  131. InOrder,
  132. Random
  133. }
  134. }
  135. }