meteorgame/Assets/Scripts/SReed33/MeteorZone.cs

117 lines
3.7 KiB
C#

// Sreed33
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MeteorZone : MonoBehaviour
{
[Header("Meteor Zone Settings")]
[Tooltip("The tag assigned to the GameObject that spawn meteors")]
[SerializeField] private string objectTag;
[Tooltip("Time between meteor spawns")]
[SerializeField] private float spawnInterval;
[Header("Meteor Prefab Assets")]
[Tooltip("Small meteor prefab")]
[SerializeField] private GameObject meteorSmall;
[Tooltip("Medium meteor prefab")]
[SerializeField] private GameObject meteorMedium;
[Tooltip("Large meteor prefab")]
[SerializeField] private GameObject meteorLarge;
[Header("Zone State")]
[Tooltip("Automatically initialized with spawn positions in this zone on game start")]
[SerializeField] private List<GameObject> meteorSpawners;
[Tooltip("A local bool that controls this zone spawning meteors")]
[SerializeField] private bool zoneSpawnMeteors = false;
[Tooltip("A local bool used to throttle the spawn rate of meteors")]
[SerializeField] private bool spawnPending = false;
// A static bool used to control the spawning of meteors across the entire level
public static bool spawnMeteors = true;
/**********************************************************************************************/
// Unity / game loop functions
// Start is called before the first frame update
void Start()
{
spawnMeteors = true;
// Check each object that makes up this meteor zone
foreach (Transform child in this.transform.parent.GetComponentsInChildren<Transform>())
{
// If the object is tagged as a metor spawner, add it to the list
if (child.gameObject.tag == objectTag) meteorSpawners.Add(child.gameObject);
}
}
void FixedUpdate()
{
// Do nothing if either local zone or level meteor bool is false
if (!spawnMeteors || !zoneSpawnMeteors) return;
// StartCoroutine only after the previous meteor is spawned
if (!spawnPending) StartCoroutine(SpawnMeteor());
}
void OnTriggerEnter(Collider other)
{
// Do nothing if the object is not a player
if (other.gameObject.tag != "Player") return;
// Set local meteor spawn bool to true; Start spawning meteors in this zone
zoneSpawnMeteors = true;
}
void OnTriggerStay(Collider other)
{
if (other.gameObject.tag != "Player") return;
// If there is a player in the zone and we are not spawning meteors, set zoneSpawnMeteors
if (!zoneSpawnMeteors) zoneSpawnMeteors = true;
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.tag != "Player") return;
// When the player leaves the zone, stop spawning meteors
zoneSpawnMeteors = false;
}
/**********************************************************************************************/
// Implementation
IEnumerator SpawnMeteor()
{
spawnPending = true;
// Wait for the set number of seconds until we spawn a meteor
yield return new WaitForSeconds(spawnInterval);
// Using the count of objects in the meteorSpawner list, get a random index to spawn at
int spawnSlot = Random.Range(0, meteorSpawners.Count);
Transform spawnPos = meteorSpawners[spawnSlot].transform;
// Using 10 values (0-9), get a large meteor(20%), medium meteor(30%), or small meteor(50%)
// + large = 0, 1; Medium = 4, 3, 2; Small = 5, 6, 7, 8, 9
int meteorType = Random.Range(0, 9);
GameObject newMeteor;
if (meteorType < 2) newMeteor = meteorLarge;
else if (meteorType < 5 && meteorType >= 2) newMeteor = meteorMedium;
else newMeteor = meteorSmall;
// Spawn this meteor
GameObject.Instantiate(newMeteor, spawnPos.position, meteorSpawners[0].transform.rotation);
// Spawn another meteor in FixedUpdate()
spawnPending = false;
}
}