diff options
author | chai <215380520@qq.com> | 2024-05-23 10:08:29 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2024-05-23 10:08:29 +0800 |
commit | 8722a9920c1f6119bf6e769cba270e63097f8e25 (patch) | |
tree | 2eaf9865de7fb1404546de4a4296553d8f68cc3b /Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/GraphUpdateUtilities.cs | |
parent | 3ba4020b69e5971bb0df7ee08b31d10ea4d01937 (diff) |
+ astar project
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/GraphUpdateUtilities.cs')
-rw-r--r-- | Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/GraphUpdateUtilities.cs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/GraphUpdateUtilities.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/GraphUpdateUtilities.cs new file mode 100644 index 0000000..a70c5eb --- /dev/null +++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Utilities/GraphUpdateUtilities.cs @@ -0,0 +1,104 @@ +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"/> + /// </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> + /// + /// Warning: This will not work for recast graphs if <see cref="GraphUpdateObject.updatePhysics"/> is enabled (the default). + /// </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; + + // Create a snapshot to allow us to revert the graphs to their original state + var snapshot = AstarPath.active.Snapshot(guo.bounds, guo.nnConstraint.graphMask); + + 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) { + AstarPath.active.AddWorkItem(snapshot.Restore); + AstarPath.active.FlushWorkItems(); + } + snapshot.Dispose(); + } finally { + graphLock.Release(); + } + + return worked; + } + } +} |