using UnityEngine; using System.Collections; using System.Collections.Generic; /// /// Manages spawning and respawning of enemy dinosaurs. /// Place this in your scene to control AI population. /// 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 activeDinos = new List(); 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); } } }