using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// Manages spawning and respawning of enemy dinosaurs.
/// Place this in your scene to control AI population.
/// </summary>
public class DinoSpawnManager : MonoBehaviour
{
[Header("Spawn Settings")]
[Tooltip("Maximum number of dinosaurs in the world")]
public int maxDinos = 5;
[Tooltip("How often to check for respawns (seconds)")]
public float respawnCheckInterval = 5f;
[Tooltip("Time between individual spawns")]
public float spawnDelay = 2f;
[Header("Spawn Locations")]
[Tooltip("Prefabs to spawn")]
public GameObject[] dinoPrefabs;
[Tooltip("Spawn points in the world")]
public Transform[] spawnPoints;
[Tooltip("Random spawn in area if no spawn points")]
public bool useRandomSpawn = true;
[Tooltip("Spawn radius from center")]
public float spawnRadius = 50f;
[Tooltip("Center point for random spawning")]
public Vector3 spawnCenter;
[Header("Debug")]
[Tooltip("Show spawn points in scene")]
public bool visualizeSpawnPoints = true;
private List<GameObject> activeDinos = new List<GameObject>();
private float respawnTimer;
private int spawnedCount;
void Start()
{
Debug.Log($"🌍 Dino Spawn Manager initialized - Max: {maxDinos}, Points: {spawnPoints.Length}");
// Initial spawn
StartCoroutine(SpawnInitialWave());
}
void Update()
{
// Clean up dead dinosaurs
CleanupDeadDinos();
// Check for respawns
respawnTimer += Time.deltaTime;
if (respawnTimer >= respawnCheckInterval)
{
respawnTimer = 0f;
CheckAndRespawn();
}
// Debug visualization
if (visualizeSpawnPoints && Application.isPlaying)
{
// Could add persistent gizmos here
}
}
IEnumerator SpawnInitialWave()
{
// Spawn initial dinosaurs with delay
for (int i = 0; i < Mathf.Min(maxDinos, dinoPrefabs.Length); i++)
{
if (dinoPrefabs[i] != null)
{
SpawnDino(dinoPrefabs[i]);
}
yield return new WaitForSeconds(spawnDelay);
}
}
void SpawnDino(GameObject prefab)
{
if (activeDinos.Count >= maxDinos)
{
return;
}
Vector3 spawnPosition = GetSpawnPosition();
// Check if position is clear
if (Physics.CheckSphere(spawnPosition, 2f, LayerMask.GetMask("Player")))
{
// Too close to player, try again with Unity 6 compatible random direction
spawnPosition += Quaternion.Euler(0f, Random.Range(0f, 360f), 0f) * Vector3.forward * 10f;
}
GameObject dino = Instantiate(prefab, spawnPosition, Quaternion.identity);
activeDinos.Add(dino);
spawnedCount++;
Debug.Log($"🦕 Spawned dino #{spawnedCount} at {spawnPosition:F1}");
}
void CheckAndRespawn()
{
int currentActive = activeDinos.Count;
if (currentActive < maxDinos && dinoPrefabs.Length > 0)
{
int toSpawn = Mathf.Min(maxDinos - currentActive, dinoPrefabs.Length);
for (int i = 0; i < toSpawn; i++)
{
int randomIndex = Random.Range(0, dinoPrefabs.Length);
SpawnDino(dinoPrefabs[randomIndex]);
}
}
}
void CleanupDeadDinos()
{
for (int i = activeDinos.Count - 1; i >= 0; i--)
{
if (activeDinos[i] == null)
{
activeDinos.RemoveAt(i);
}
}
}
Vector3 GetSpawnPosition()
{
// Use spawn points if available
if (spawnPoints.Length > 0)
{
Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)];
return spawnPoint.position;
}
// Random spawn in area
if (useRandomSpawn)
{
float angle = Random.Range(0f, 360f) * Mathf.Deg2Rad;
float radius = Random.Range(10f, spawnRadius);
return new Vector3(
spawnCenter.x + Mathf.Cos(angle) * radius,
0f,
spawnCenter.z + Mathf.Sin(angle) * radius
);
}
return Vector3.zero;
}
void OnDrawGizmosSelected()
{
// Draw spawn points
if (spawnPoints != null)
{
Gizmos.color = Color.green;
foreach (Transform point in spawnPoints)
{
if (point != null)
{
Gizmos.DrawWireSphere(point.position, 3f);
}
}
}
// Draw spawn radius
if (useRandomSpawn)
{
Gizmos.color = new Color(0, 1, 0, 0.2f);
Gizmos.DrawWireSphere(spawnCenter, spawnRadius);
}
}
}