using System.Collections; using System.Collections.Generic; using UnityEngine; public class CharacterSpawner : MonoBehaviour { public List characterPrefabs; // 所有可用的角色预制体 public Transform[] spawnPoints; // 生成点 public Vector2 IntervalBetweenWave = new Vector2(6f, 10f); // 生成间隔 public int minSpawnCount = 1; // 最少生成角色数 public int maxSpawnCount = 3; // 最多生成角色数 public Vector2 IntervalBetweenCharacter = new Vector2(1f, 3f); // 角色生成间隔 void Start() { StartCoroutine(SpawnCoroutine()); // 进入循环 } private IEnumerator SpawnCoroutine() { while (true) { int spawnCount = Random.Range(minSpawnCount, maxSpawnCount + 1); // 确保包含 maxSpawnCount List selectedCharacters = PickUpCharacterToSpawn(spawnCount); // 选定本轮要生成的角色 foreach (GameObject characterPrefab in selectedCharacters) { SpawnCharacter(characterPrefab); yield return new WaitForSeconds(Random.Range(IntervalBetweenCharacter.x, IntervalBetweenCharacter.y)); // 角色生成间隔 } yield return new WaitForSeconds(Random.Range(IntervalBetweenWave.x, IntervalBetweenWave.y)); // 等待下一轮生成 } } private void SpawnCharacter(GameObject characterPrefab) { Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)]; // 随机选择生成点 GameObject obj = Instantiate(characterPrefab, spawnPoint.position, Quaternion.identity,this.transform); BackgroundMoveableCharacter character = obj.GetComponent(); // 计算方向:左边出生向右走,右边出生向左走 bool isFacingRight = character.defaultFacingRight; bool movingRight = spawnPoint.position.x < 0; // 左边生成则向右,右边生成则向左 character.direction = movingRight ? Vector2.right : Vector2.left; // 设定目标边界(取决于方向) float leftBoundary = isFacingRight ? -15f : -4f; float rightBoundary = isFacingRight ? 15f : 6f; float targetBoundary = movingRight ? rightBoundary : leftBoundary; // 绑定边界检测脚本 BoundaryDestroy boundaryDestroy = obj.AddComponent(); boundaryDestroy.SetBoundary(targetBoundary, movingRight); } private List PickUpCharacterToSpawn(int num) { List availableCharacters = GetAvailableCharacters(); // 获取当前可用的角色 List selectedCharacters = new List(); if (availableCharacters.Count == 0) return selectedCharacters; // 如果没有可用角色,直接返回空列表 int spawnCount = Mathf.Min(num, availableCharacters.Count); // 确保不会超过可用角色数 for (int i = 0; i < spawnCount; i++) { int randomIndex = Random.Range(0, availableCharacters.Count); selectedCharacters.Add(availableCharacters[randomIndex]); // ✅ 立即从列表中移除,确保不会重复选择 availableCharacters.RemoveAt(randomIndex); } return selectedCharacters; } private List GetAvailableCharacters() { List available = new List(characterPrefabs); // 复制所有角色 GameObject[] existingCharacters = GameObject.FindGameObjectsWithTag("MoveableCharacter"); // 获取当前场景中的角色 // 遍历场景中已经存在的角色 foreach (GameObject existing in existingCharacters) { BackgroundMoveableCharacter character = existing.GetComponent(); if (character != null) { string existingName = existing.name.Replace("(Clone)", "").Trim(); available.RemoveAll(c => c.name == existingName); } } return available; } }