sea-battle/Assets/Scripts/Pirate/PointsManager.cs
2026-01-09 08:45:22 +03:00

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;
}
}