102 lines
4.0 KiB
C#
102 lines
4.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class CharacterSpawner : MonoBehaviour
|
|
{
|
|
public List<GameObject> 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<GameObject> 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<BackgroundMoveableCharacter>();
|
|
|
|
// 计算方向:左边出生向右走,右边出生向左走
|
|
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>();
|
|
boundaryDestroy.SetBoundary(targetBoundary, movingRight);
|
|
}
|
|
|
|
|
|
|
|
private List<GameObject> PickUpCharacterToSpawn(int num)
|
|
{
|
|
List<GameObject> availableCharacters = GetAvailableCharacters(); // 获取当前可用的角色
|
|
List<GameObject> selectedCharacters = new List<GameObject>();
|
|
|
|
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<GameObject> GetAvailableCharacters()
|
|
{
|
|
List<GameObject> available = new List<GameObject>(characterPrefabs); // 复制所有角色
|
|
GameObject[] existingCharacters = GameObject.FindGameObjectsWithTag("MoveableCharacter"); // 获取当前场景中的角色
|
|
|
|
// 遍历场景中已经存在的角色
|
|
foreach (GameObject existing in existingCharacters)
|
|
{
|
|
BackgroundMoveableCharacter character = existing.GetComponent<BackgroundMoveableCharacter>();
|
|
if (character != null)
|
|
{
|
|
string existingName = existing.name.Replace("(Clone)", "").Trim();
|
|
available.RemoveAll(c => c.name == existingName);
|
|
}
|
|
}
|
|
|
|
return available;
|
|
}
|
|
}
|