using UnityEngine; using UnityEngine.AI; using System.Collections.Generic; using BITKit; namespace Net.Project.B.AI { public class SpawnManager : MonoBehaviour { public float spawnRadius = 20f; // 刷怪区域半径 public int maxSpawnPoints = 10; // 最大刷怪点数量 public float minDistanceBetweenSpawns = 5f; // 最小刷怪点间距 public float clearanceCheckDistance = 3f; // 空旷度检测半径 public GameObject enemyPrefab; // 怪物预制体 void Start() { List spawnPoints = GenerateSpawnPoints(transform.position, spawnRadius, minDistanceBetweenSpawns, maxSpawnPoints); foreach (var point in spawnPoints) { Instantiate(enemyPrefab, point, Quaternion.identity); Debug.DrawRay(point, Vector3.up * 2, Color.green, 5f); // 可视化调试 } } List GenerateSpawnPoints(Vector3 center, float radius, float minDist, int maxPoints) { List spawnPoints = new List(); int attempts = 0; while (spawnPoints.Count < maxPoints && attempts < maxPoints * 10) { Vector3 randomPoint = center + Random.insideUnitSphere * radius; randomPoint.y = center.y; // 保持 Y 轴位置 if (NavMesh.SamplePosition(randomPoint, out NavMeshHit hit, 2f, NavMesh.AllAreas)) { if (IsClearArea(hit.position, minDist, spawnPoints) && IsSpacious(hit.position)) { spawnPoints.Add(hit.position); } } attempts++; } return spawnPoints; } // 确保刷怪点不会过近 bool IsClearArea(Vector3 pos, float minDist, List points) { foreach (var p in points) { if (Vector3.Distance(p, pos) < minDist) return false; } return true; } // 确保周围没有障碍物,区域足够空旷 bool IsSpacious(Vector3 pos) { for (int i = 0; i < 8; i++) { Vector3 dir = Quaternion.Euler(0, i * 45, 0) * Vector3.forward * clearanceCheckDistance; if (NavMesh.Raycast(pos, pos + dir, out _, NavMesh.AllAreas)) { return false; // 遇到障碍,位置不合适 } } return true; } #if UNITY_EDITOR [BIT] private void Sample() { _spawnPoints = GenerateSpawnPoints(transform.position, spawnRadius, minDistanceBetweenSpawns, maxSpawnPoints); } private List _spawnPoints = new(); // 可视化调试刷怪点 void OnDrawGizmos() { if (Application.isPlaying) return; Gizmos.color = Color.red; foreach (var point in _spawnPoints) { Gizmos.DrawSphere(point, 0.5f); } } #endif } }