121 lines
3.1 KiB
C#
121 lines
3.1 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
public class PointsManager : MonoBehaviour
|
|
{
|
|
[Header("Òî÷êè äëÿ ðàçíûõ çàäà÷")]
|
|
public Transform[] dancePoints;
|
|
public Transform[] shootPoints;
|
|
|
|
// Ñëîâàðü: èìÿ ãðóïïû çàíÿòûå òî÷êè
|
|
private readonly Dictionary<string, HashSet<Transform>> occupied = new();
|
|
|
|
private void Awake()
|
|
{
|
|
// Èíèöèàëèçàöèÿ ãðóïï
|
|
occupied["dance"] = new HashSet<Transform>();
|
|
occupied["shoot"] = new HashSet<Transform>();
|
|
|
|
ValidateOnNavMesh(dancePoints);
|
|
ValidateOnNavMesh(shootPoints);
|
|
}
|
|
|
|
private void ValidateOnNavMesh(Transform[] points)
|
|
{
|
|
foreach (var p in points)
|
|
{
|
|
if (p == null) continue;
|
|
if (NavMesh.SamplePosition(p.position, out NavMeshHit hit, 2f, NavMesh.AllAreas))
|
|
{
|
|
p.position = hit.position;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning($"{p.name} íå ïîïàë íà NavMesh!");
|
|
}
|
|
}
|
|
}
|
|
|
|
public Transform GetRandomFreePoint(string group, Transform[] points)
|
|
{
|
|
if (points == null || points.Length == 0) return null;
|
|
|
|
var freePoints = new List<Transform>();
|
|
foreach (var p in points)
|
|
{
|
|
if (!occupied[group].Contains(p))
|
|
freePoints.Add(p);
|
|
}
|
|
|
|
if (freePoints.Count == 0) return null;
|
|
|
|
Transform chosen = freePoints[Random.Range(0, freePoints.Count)];
|
|
occupied[group].Add(chosen);
|
|
return chosen;
|
|
}
|
|
|
|
public Transform GetNearestFreePoint(string group, Transform[] points, Vector3 fromPosition)
|
|
{
|
|
Transform nearest = null;
|
|
float minDist = float.MaxValue;
|
|
|
|
foreach (var p in points)
|
|
{
|
|
if (occupied[group].Contains(p)) continue;
|
|
|
|
float dist = Vector3.Distance(fromPosition, p.position);
|
|
if (dist < minDist)
|
|
{
|
|
minDist = dist;
|
|
nearest = p;
|
|
}
|
|
}
|
|
|
|
if (nearest != null)
|
|
occupied[group].Add(nearest);
|
|
|
|
return nearest;
|
|
}
|
|
|
|
public void FreePoint(string group, Transform point)
|
|
{
|
|
occupied[group].Remove(point);
|
|
}
|
|
|
|
|
|
public bool HasLineOfSight(Transform from, Transform to)
|
|
{
|
|
if (from == null || to == null) return false;
|
|
|
|
Vector3 origin = from.position + Vector3.up * 1.5f;
|
|
Vector3 target = to.position + Vector3.up * 1.0f;
|
|
Vector3 direction = (target - origin).normalized;
|
|
float distance = Vector3.Distance(origin, target);
|
|
|
|
RaycastHit[] hits = Physics.RaycastAll(origin, direction, distance);
|
|
|
|
foreach (var hit in hits)
|
|
{
|
|
// èãíîðèðóåì ñàìîãî âðàãà
|
|
if (hit.transform == to || hit.transform.IsChildOf(to)) continue;
|
|
|
|
// åñëè ÷òî-òî ïîïàëîñü ðàíüøå âðàãà — LOS çàêðûò
|
|
#if UNITY_EDITOR
|
|
Debug.DrawLine(origin, hit.point, Color.red, 1f);
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
Debug.DrawLine(origin, target, Color.green, 1f);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|