123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- using System.Collections.Generic;
- using Pathfinding.Util;
- namespace Pathfinding {
- /// <summary>
- /// Contains useful functions for updating graphs.
- /// This class works a lot with the GraphNode class, a useful function to get nodes is <see cref="AstarPath.GetNearest"/>.
- ///
- /// See: <see cref="AstarPath.GetNearest"/>
- /// See: <see cref="Pathfinding.PathUtilities"/>
- ///
- /// Since: Added in 3.1
- /// </summary>
- public static class GraphUpdateUtilities {
- /// <summary>
- /// Updates graphs and checks if all nodes are still reachable from each other.
- /// Graphs are updated, then a check is made to see if the nodes are still reachable from each other.
- /// If they are not, the graphs are reverted to before the update and false is returned.
- /// This is slower than a normal graph update.
- /// All queued graph updates and thread safe callbacks will be flushed during this function.
- ///
- /// Returns: True if the given nodes are still reachable from each other after the guo has been applied. False otherwise.
- ///
- /// <code>
- /// var guo = new GraphUpdateObject(tower.GetComponent<Collider>().bounds);
- /// var spawnPointNode = AstarPath.active.GetNearest(spawnPoint.position).node;
- /// var goalNode = AstarPath.active.GetNearest(goalPoint.position).node;
- ///
- /// if (GraphUpdateUtilities.UpdateGraphsNoBlock(guo, spawnPointNode, goalNode, false)) {
- /// // Valid tower position
- /// // Since the last parameter (which is called "alwaysRevert") in the method call was false
- /// // The graph is now updated and the game can just continue
- /// } else {
- /// // Invalid tower position. It blocks the path between the spawn point and the goal
- /// // The effect on the graph has been reverted
- /// Destroy(tower);
- /// }
- /// </code>
- /// </summary>
- /// <param name="guo">The GraphUpdateObject to update the graphs with</param>
- /// <param name="node1">Node which should have a valid path to node2. All nodes should be walkable or false will be returned.</param>
- /// <param name="node2">Node which should have a valid path to node1. All nodes should be walkable or false will be returned.</param>
- /// <param name="alwaysRevert">If true, reverts the graphs to the old state even if no blocking occurred</param>
- public static bool UpdateGraphsNoBlock (GraphUpdateObject guo, GraphNode node1, GraphNode node2, bool alwaysRevert = false) {
- List<GraphNode> buffer = ListPool<GraphNode>.Claim();
- buffer.Add(node1);
- buffer.Add(node2);
- bool worked = UpdateGraphsNoBlock(guo, buffer, alwaysRevert);
- ListPool<GraphNode>.Release(ref buffer);
- return worked;
- }
- /// <summary>
- /// Updates graphs and checks if all nodes are still reachable from each other.
- /// Graphs are updated, then a check is made to see if the nodes are still reachable from each other.
- /// If they are not, the graphs are reverted to before the update and false is returned.
- /// This is slower than a normal graph update.
- /// All queued graph updates will be flushed during this function.
- ///
- /// Returns: True if the given nodes are still reachable from each other after the guo has been applied. False otherwise.
- /// </summary>
- /// <param name="guo">The GraphUpdateObject to update the graphs with</param>
- /// <param name="nodes">Nodes which should have valid paths between them. All nodes should be walkable or false will be returned.</param>
- /// <param name="alwaysRevert">If true, reverts the graphs to the old state even if no blocking occurred</param>
- public static bool UpdateGraphsNoBlock (GraphUpdateObject guo, List<GraphNode> nodes, bool alwaysRevert = false) {
- bool worked;
- // Pause pathfinding while modifying the graphs
- var graphLock = AstarPath.active.PausePathfinding();
- try {
- // Make sure any pending graph updates have been done before we start
- AstarPath.active.FlushGraphUpdates();
- // Make sure all nodes are walkable
- for (int i = 0; i < nodes.Count; i++) if (!nodes[i].Walkable) return false;
- // Track changed nodes to enable reversion of the guo
- guo.trackChangedNodes = true;
- AstarPath.active.UpdateGraphs(guo);
- // Update the graphs immediately
- AstarPath.active.FlushGraphUpdates();
- // Check if all nodes are in the same area and that they are walkable, i.e that there are paths between all of them
- worked = PathUtilities.IsPathPossible(nodes);
- // If it did not work, revert the GUO
- if (!worked || alwaysRevert) {
- guo.RevertFromBackup();
- // Recalculate connected components
- AstarPath.active.hierarchicalGraph.RecalculateIfNecessary();
- }
- } finally {
- graphLock.Release();
- }
- // Disable tracking nodes, not strictly necessary, but will slightly reduce the cance that some user causes errors
- guo.trackChangedNodes = false;
- return worked;
- }
- }
- }
|