103 lines
3.1 KiB
C#
103 lines
3.1 KiB
C#
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<Vector3> 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<Vector3> GenerateSpawnPoints(Vector3 center, float radius, float minDist, int maxPoints)
|
|
{
|
|
List<Vector3> spawnPoints = new List<Vector3>();
|
|
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<Vector3> 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<Vector3> _spawnPoints = new();
|
|
|
|
// 可视化调试刷怪点
|
|
void OnDrawGizmos()
|
|
{
|
|
if (Application.isPlaying) return;
|
|
Gizmos.color = Color.red;
|
|
|
|
foreach (var point in _spawnPoints)
|
|
{
|
|
Gizmos.DrawSphere(point, 0.5f);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
} |