/// Finds shortest path between Nodes. /// Once the path is found, it will return the path as List of Positions ( not Nodes, but vector3. If you need Nodes, use FindShortestPathOfNodes). /// <returns> Returns list of **Positions**</returns> /// <param name="startNodeID">Find the path from this node</param> /// <param name="endNodeID">Find the path to this node</param> /// <param name="pathType">Path type. It can be a straight line or curved path</param> /// <param name="executionType">Synchronous is immediate and locks the control till path is found and returns the path. /// Asynchronous type runs in coroutines with out locking the control. If you have more than 50 Nodes, Asynchronous is recommended</param> /// <param name="searchMode"> This is still WIP. For now, Intermediate and Complex does a tad bit more calculations to make the path even shorter</param> /// <param name="OnPathFound">Callback once the path is found</param> public static void FindShortestPathOfPoints(this PathFinder manager, Vector3 startPoint, Vector3 endPoint, PathLineType pathType, Execution executionType, SearchMode searchMode, System.Action <List <Vector3> > OnPathFound) { PathFollowerUtility.FindShortestPathOfPoints_Internal(manager, startPoint, endPoint, pathType, executionType, searchMode, OnPathFound); }
internal static void FindShortestPathOfPoints_Internal(PathFinder manager, Vector3 startPoint, Vector3 endPoint, PathLineType pathType, Execution execution, SearchMode searchMode, System.Action <List <Vector3> > OnPathFound) { bool makeItMoreAccurate = searchMode == SearchMode.Intermediate || searchMode == SearchMode.Complex; int nearestPointFromStart = manager.FindNearestNode(startPoint); int nearestPointFromEnd = -1; if (nearestPointFromStart != -1) { nearestPointFromEnd = manager.FindNearestNode(endPoint); } if (QPathFinder.Logger.CanLogInfo) { QPathFinder.Logger.LogInfo("Nearest point from start" + startPoint + " is " + nearestPointFromStart, true); } if (QPathFinder.Logger.CanLogInfo) { QPathFinder.Logger.LogInfo("Nearest point from end:" + endPoint + " is " + nearestPointFromEnd, true); } if (nearestPointFromEnd == -1 || nearestPointFromStart == -1) { if (QPathFinder.Logger.CanLogError) { QPathFinder.Logger.LogError("Could not find path between " + nearestPointFromStart + " and " + nearestPointFromEnd, true); } OnPathFound(null); return; } float startTime = Time.realtimeSinceStartup; System.Action <List <Node> > onPathOfNodesFound = delegate(List <Node> nodes) { if (nodes == null || nodes.Count == 0) { OnPathFound(null); return; } List <System.Object> allNodes = new List <System.Object>(); if (nodes != null) { foreach (var a in nodes) { allNodes.Add(a); } } if (QPathFinder.Logger.CanLogInfo) { QPathFinder.Logger.LogInfo("Search Mode " + searchMode.ToString() + " opted", true); } if (makeItMoreAccurate) { if (allNodes.Count > 1) { Vector3 shortestPointOnPath; int nearestNode = -1; Path currentPath = null; int shortestPathID = -1; { nearestNode = ((Node)allNodes[0]).autoGeneratedID; shortestPathID = -1; currentPath = manager.graphData.GetPathBetween(GetNodeFromNodeOrVector(allNodes, 0), GetNodeFromNodeOrVector(allNodes, 1)); if (currentPath != null) { shortestPointOnPath = GetClosestPointOnAnyPath(nearestNode, manager, startPoint, out shortestPathID); if (shortestPathID == currentPath.autoGeneratedID) { allNodes[0] = shortestPointOnPath; } else { allNodes.Insert(0, shortestPointOnPath); } } else { if (QPathFinder.Logger.CanLogError) { QPathFinder.Logger.LogInfo("Error occured while finding path"); } } } { shortestPathID = -1; nearestNode = ((Node)allNodes[allNodes.Count - 1]).autoGeneratedID; currentPath = manager.graphData.GetPathBetween(GetNodeFromNodeOrVector(allNodes, allNodes.Count - 2), GetNodeFromNodeOrVector(allNodes, allNodes.Count - 1)); if (currentPath != null) { shortestPointOnPath = GetClosestPointOnAnyPath(nearestNode, manager, endPoint, out shortestPathID); if (shortestPathID == currentPath.autoGeneratedID) { allNodes[allNodes.Count - 1] = shortestPointOnPath; } else { allNodes.Add(shortestPointOnPath); } } else { if (QPathFinder.Logger.CanLogError) { QPathFinder.Logger.LogInfo("Error occured while finding path"); } } } } else { if (QPathFinder.Logger.CanLogWarning) { QPathFinder.Logger.LogWarning("Unable to get the best result due to less node count", true); } } } List <Vector3> path = null; { allNodes.Insert(0, startPoint); allNodes.Add(endPoint); path = (pathType == PathLineType.Straight ? GetStraightPathPoints(allNodes) : GetCatmullRomCurvePathPoints(allNodes)); } if (QPathFinder.Logger.CanLogInfo) { for (int i = 1; i < path.Count; i++) { Debug.DrawLine(path[i - 1], path[i], Color.red, QPathFinder.Logger.DrawLineDuration); } } OnPathFound(path); }; manager.FindShortestPathOfNodes(nearestPointFromStart, nearestPointFromEnd, execution, onPathOfNodesFound); }
/// Finds shortest path between Nodes. /// Once the path is found, it will return the path as List of Positions (not Nodes, but vector3. If you need Nodes, use FindShortestPathOfNodes). /// <returns> Returns list of **Positions**</returns> /// <param name="startNodeID">Find the path from this node</param> /// <param name="endNodeID">Find the path to this node</param> /// <param name="pathType">Path type. It can be a straight line or curved path</param> /// <param name="executionType">Synchronous is immediate and locks the control till path is found and returns the path. /// Asynchronous type runs in coroutines without locking the control. If you have more than 50 Nodes, Asynchronous is recommended</param> /// <param name="OnPathFound">Callback once the path is found</param> public static void FindShortestPathOfPoints(this PathFinder manager, int startNodeID, int endNodeID, PathLineType pathType, Execution executionType, System.Action <List <Vector3> > OnPathFound) { PathFollowerUtility.FindShortestPathOfPoints_Internal(manager, startNodeID, endNodeID, pathType, executionType, OnPathFound); }
// // *** PRIVATE AND INTERNAL *** #region PRIVATE AND INTERNAL internal static void FindShortestPathOfPoints_Internal(PathFinder manager, int startNodeID, int endNodeID, PathLineType pathType, Execution execution, System.Action <List <Vector3> > OnPathFound) { int nearestPointFromStart = startNodeID; int nearestPointFromEnd = endNodeID; if (nearestPointFromEnd == -1 || nearestPointFromStart == -1) { if (QPathFinder.Logger.CanLogError) { QPathFinder.Logger.LogError("Could not find path between " + nearestPointFromStart + " and " + nearestPointFromEnd, true); } OnPathFound(null); return; } float startTime = Time.realtimeSinceStartup; System.Action <List <Node> > onPathOfNodesFound = delegate(List <Node> nodes) { if (nodes == null || nodes.Count == 0) { OnPathFound(null); } List <System.Object> allNodes = new List <System.Object>(); List <Vector3> path = null; if (nodes != null) { foreach (var a in nodes) { allNodes.Add(a.Position); } } path = (pathType == PathLineType.Straight ? GetStraightPathPoints(allNodes) : GetCatmullRomCurvePathPoints(allNodes)); if (QPathFinder.Logger.CanLogInfo) { for (int i = 1; i < path.Count; i++) { Debug.DrawLine(path[i - 1], path[i], Color.red, QPathFinder.Logger.DrawLineDuration); } } OnPathFound(path); }; manager.FindShortestPathOfNodes(nearestPointFromStart, nearestPointFromEnd, execution, onPathOfNodesFound); }