using Gley.UrbanSystem.Internal; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Gley.TrafficSystem.Internal { /// /// Get path to a destination waypoint. /// internal class PathFindingManager { private readonly GridDataHandler _gridDataHandler; private readonly PathFindingDataHandler _trafficPathFindingDataHandler; private readonly AStar _aStar; internal PathFindingManager (GridDataHandler gridDataHandler, PathFindingDataHandler trafficPathFindingDataHandler) { _gridDataHandler = gridDataHandler; _trafficPathFindingDataHandler = trafficPathFindingDataHandler; _aStar = new AStar (); } internal List GetPathToDestination(int vehicleIndex, int currentWaypointIndex, Vector3 position, VehicleTypes vehicleType) { if (currentWaypointIndex < 0) { Debug.LogWarning($"Cannot find route to destination. Vehicle at index {vehicleIndex} is disabled or has an invalid target waypoint"); return null; } int closestWaypointIndex = GetClosestPathFindingWaypoint(position, (int)vehicleType); if (closestWaypointIndex < 0) { Debug.LogWarning("No waypoint found closer to destination"); return null; } List path = _aStar.FindPath(currentWaypointIndex, closestWaypointIndex, (int)vehicleType, _trafficPathFindingDataHandler.GetPathFindingWaypoints()); if (path != null) { return path; } Debug.LogWarning($"No path found for vehicle {vehicleIndex} to {position}"); return null; } internal List GetPath(Vector3 startPosition, Vector3 endPosition, VehicleTypes vehicleType) { var startIndex = GetClosestPathFindingWaypoint(startPosition, (int)vehicleType); if(startIndex== TrafficSystemConstants.INVALID_WAYPOINT_INDEX) { Debug.LogWarning($"No traffic waypoint found close to {startPosition}"); return null; } var endIndex = GetClosestPathFindingWaypoint(endPosition, (int)vehicleType); if(endIndex == TrafficSystemConstants.INVALID_WAYPOINT_INDEX) { Debug.LogWarning($"No traffic waypoint found closed to {endPosition}"); return null; } var path = _aStar.FindPath(startIndex, endIndex, (int)vehicleType, _trafficPathFindingDataHandler.GetPathFindingWaypoints()); if (path == null) { Debug.LogWarning($"No path found from {startPosition} to {endPosition}"); } return path; } private int GetClosestPathFindingWaypoint(Vector3 position, int type) { List possibleWaypoints = _gridDataHandler.GetTrafficWaypointsAroundPosition(position); if (possibleWaypoints.Count == 0) { return TrafficSystemConstants.INVALID_WAYPOINT_INDEX; } float distance = float.MaxValue; int waypointIndex = TrafficSystemConstants.INVALID_WAYPOINT_INDEX; foreach (int waypoint in possibleWaypoints) { if (_trafficPathFindingDataHandler.GetAllowedAgents(waypoint).Contains(type)) { float newDistance = Vector3.SqrMagnitude(_trafficPathFindingDataHandler.GetWaypointPosition(waypoint) - position); if (newDistance < distance) { distance = newDistance; waypointIndex = waypoint; } } } return waypointIndex; } } }