summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-05-23 10:08:29 +0800
committerchai <215380520@qq.com>2024-05-23 10:08:29 +0800
commit8722a9920c1f6119bf6e769cba270e63097f8e25 (patch)
tree2eaf9865de7fb1404546de4a4296553d8f68cc3b /Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs
parent3ba4020b69e5971bb0df7ee08b31d10ea4d01937 (diff)
+ astar project
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs150
1 files changed, 150 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs
new file mode 100644
index 0000000..b743983
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/FloodPathTracer.cs
@@ -0,0 +1,150 @@
+using UnityEngine;
+
+namespace Pathfinding {
+ /// <summary>
+ /// Restrict suitable nodes by if they have been searched by a FloodPath.
+ ///
+ /// Suitable nodes are in addition to the basic contraints, only the nodes which return true on a FloodPath.HasPathTo (node) call.
+ /// See: Pathfinding.FloodPath
+ /// See: Pathfinding.FloodPathTracer
+ /// </summary>
+ public class FloodPathConstraint : NNConstraint {
+ readonly FloodPath path;
+
+ public FloodPathConstraint (FloodPath path) {
+ if (path == null) { Debug.LogWarning("FloodPathConstraint should not be used with a NULL path"); }
+ this.path = path;
+ }
+
+ public override bool Suitable (GraphNode node) {
+ return base.Suitable(node) && path.HasPathTo(node);
+ }
+ }
+
+ /// <summary>
+ /// Traces a path created with the Pathfinding.FloodPath.
+ ///
+ /// See Pathfinding.FloodPath for examples on how to use this path type
+ ///
+ /// [Open online documentation to see images]
+ /// </summary>
+ public class FloodPathTracer : ABPath {
+ /// <summary>Reference to the FloodPath which searched the path originally</summary>
+ protected FloodPath flood;
+
+ protected override bool hasEndPoint => false;
+
+ /// <summary>
+ /// Default constructor.
+ /// Do not use this. Instead use the static Construct method which can handle path pooling.
+ /// </summary>
+ public FloodPathTracer () {}
+
+ public static FloodPathTracer Construct (Vector3 start, FloodPath flood, OnPathDelegate callback = null) {
+ var p = PathPool.GetPath<FloodPathTracer>();
+
+ p.Setup(start, flood, callback);
+ return p;
+ }
+
+ protected void Setup (Vector3 start, FloodPath flood, OnPathDelegate callback) {
+ this.flood = flood;
+
+ if (flood == null || flood.PipelineState < PathState.Returning) {
+ throw new System.ArgumentException("You must supply a calculated FloodPath to the 'flood' argument");
+ }
+
+ base.Setup(start, flood.originalStartPoint, callback);
+ nnConstraint = new FloodPathConstraint(flood);
+ }
+
+ protected override void Reset () {
+ base.Reset();
+ flood = null;
+ }
+
+ /// <summary>
+ /// Initializes the path.
+ /// Traces the path from the start node.
+ /// </summary>
+ protected override void Prepare () {
+ if (!this.flood.IsValid(pathHandler.nodeStorage)) {
+ FailWithError("The flood path is invalid because nodes have been destroyed since it was calculated. Please recalculate the flood path.");
+ return;
+ }
+
+ base.Prepare();
+
+ if (CompleteState == PathCompleteState.NotCalculated) {
+ for (uint i = 0; i < pathHandler.numTemporaryNodes; i++) {
+ var nodeIndex = pathHandler.temporaryNodeStartIndex + i;
+ ref var tempNode = ref pathHandler.GetTemporaryNode(nodeIndex);
+ if (tempNode.type == TemporaryNodeType.Start) {
+ var node = pathHandler.GetNode(tempNode.associatedNode);
+
+ // This is guaranteed by the FloodPathConstraint
+ bool found = false;
+ for (uint k = 0; k < node.PathNodeVariants; k++) {
+ if (flood.GetParent(node.NodeIndex + k) != 0) {
+ found = true;
+ CompleteState = PathCompleteState.Complete;
+ Trace(node.NodeIndex + k);
+ break;
+ }
+ }
+ if (!found) {
+ FailWithError("The flood path did not contain any information about the end node. Have you modified the path's nnConstraint to an instance which does not subclass FloodPathConstraint?");
+ }
+ return;
+ }
+ }
+
+ FailWithError("Could not find a valid start node");
+ }
+ }
+
+ protected override void CalculateStep (long targetTick) {
+ if (CompleteState != PathCompleteState.Complete) throw new System.Exception("Something went wrong. At this point the path should be completed");
+ }
+
+ /// <summary>
+ /// Traces the calculated path from the start node to the end.
+ /// This will build an array (<see cref="path)"/> of the nodes this path will pass through and also set the <see cref="vectorPath"/> array to the <see cref="path"/> arrays positions.
+ /// This implementation will use the <see cref="flood"/> (FloodPath) to trace the path from precalculated data.
+ /// </summary>
+ protected override void Trace (uint fromPathNodeIndex) {
+ uint pathNodeIndex = fromPathNodeIndex;
+ int count = 0;
+
+ while (pathNodeIndex != 0) {
+ if ((pathNodeIndex & FloodPath.TemporaryNodeBit) != 0) {
+ // Skip over temporary nodes
+ pathNodeIndex = flood.GetParent(pathNodeIndex & ~FloodPath.TemporaryNodeBit);
+ } else {
+ var node = pathHandler.GetNode(pathNodeIndex);
+ if (node == null) {
+ FailWithError("A node in the path has been destroyed. The FloodPath needs to be recalculated before you can use a FloodPathTracer.");
+ return;
+ }
+ if (!CanTraverse(node)) {
+ FailWithError("A node in the path is no longer walkable. The FloodPath needs to be recalculated before you can use a FloodPathTracer.");
+ return;
+ }
+ path.Add(node);
+ vectorPath.Add((Vector3)node.position);
+ var next = flood.GetParent(pathNodeIndex);
+ if (next == pathNodeIndex) {
+ break;
+ }
+ pathNodeIndex = next;
+ }
+
+ count++;
+ if (count > 10000) {
+ Debug.LogWarning("Infinite loop? >10000 node path. Remove this message if you really have that long paths");
+ break;
+ }
+ }
+ }
+ }
+}