summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/XPath.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/XPath.cs
parent3ba4020b69e5971bb0df7ee08b31d10ea4d01937 (diff)
+ astar project
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/XPath.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/XPath.cs131
1 files changed, 131 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/XPath.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/XPath.cs
new file mode 100644
index 0000000..3e79d3b
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Pathfinders/XPath.cs
@@ -0,0 +1,131 @@
+using UnityEngine;
+
+namespace Pathfinding {
+ /// <summary>
+ /// Extended Path.
+ ///
+ /// This is the same as a standard path but it is possible to customize when the target should be considered reached.
+ /// Can be used to for example signal a path as complete when it is within a specific distance from the target.
+ ///
+ /// Note: More customizations does make it slower to calculate than an ABPath but not by very much.
+ ///
+ /// See: Pathfinding.PathEndingCondition
+ ///
+ /// Deprecated: Use an <see cref="ABPath"/> with the <see cref="ABPath.endingCondition"/> field instead.
+ /// </summary>
+ [System.Obsolete("Use an ABPath with the ABPath.endingCondition field instead")]
+ public class XPath : ABPath {
+ [System.Obsolete("Use ABPath.Construct instead")]
+ public new static ABPath Construct (Vector3 start, Vector3 end, OnPathDelegate callback = null) {
+ return ABPath.Construct(start, end, callback);
+ }
+ }
+
+ /// <summary>
+ /// Customized ending condition for a path.
+ ///
+ /// If you want to create a path which needs a more complex ending condition than just reaching the end node, you can use this class.
+ /// Inherit from this class and override the <see cref="TargetFound"/> function to implement you own ending condition logic.
+ ///
+ /// For example, you might want to create an Ending Condition which stop searching when a node is close enough to a given point.
+ /// Then what you do is that you create your own class, let's call it MyEndingCondition and override the function TargetFound to specify our own logic.
+ /// We want to inherit from ABPathEndingCondition because only ABPaths have end points defined.
+ ///
+ /// <code>
+ /// public class MyEndingCondition : ABPathEndingCondition {
+ /// // Maximum world distance to the target node before terminating the path
+ /// public float maxDistance = 10;
+ ///
+ /// // Reuse the constructor in the superclass
+ /// public MyEndingCondition (ABPath p) : base(p) {}
+ ///
+ /// public override bool TargetFound (GraphNode node, uint H, uint G) {
+ /// return ((Vector3)node.position - abPath.originalEndPoint).sqrMagnitude <= maxDistance*maxDistance;
+ /// }
+ /// }
+ /// </code>
+ ///
+ /// The TargetReached method in the code above checks if the node that the path is currently searching is close enough to the target point for us to consider it a valid target node.
+ /// If true is returned, the path will immediately terminate and return the path to that point.
+ ///
+ /// To use a custom endition condition, you have to instantiate your class and then assign it to <see cref="ABPath.endingCondition"/> field.
+ ///
+ /// <code>
+ /// ABPath myPath = ABPath.Construct(startPoint, endPoint);
+ /// var ec = new MyEndingCondition(myPath);
+ /// ec.maxDistance = 100; // Or some other value
+ /// myPath.endingCondition = ec;
+ ///
+ /// // Calculate the path!
+ /// seeker.StartPath(myPath);
+ /// </code>
+ ///
+ /// Where seeker is a <see cref="Seeker"/> component.
+ ///
+ /// If ending conditions are used that are not centered around the endpoint of the path,
+ /// then the heuristic (<see cref="AstarPath.heuristic"/>) must be set to None to guarantee that the path is still optimal.
+ /// However, the performance impact of setting the heuristic to None is quite large, so you might want to try to run it with the default
+ /// heuristic to see if the path is good enough for your use case anyway.
+ ///
+ /// See: <see cref="ABPath"/>
+ /// See: <see cref="ConstantPath"/>
+ /// </summary>
+ public abstract class PathEndingCondition {
+ /// <summary>Path which this ending condition is used on</summary>
+ protected Path path;
+
+ protected PathEndingCondition () {}
+
+ public PathEndingCondition (Path p) {
+ if (p == null) throw new System.ArgumentNullException("p");
+ this.path = p;
+ }
+
+ /// <summary>Has the ending condition been fulfilled.</summary>
+ /// <param name="node">The current node.</param>
+ /// <param name="H">Heuristic score. See Pathfinding.PathNode.H</param>
+ /// <param name="G">Cost to reach this node. See Pathfinding.PathNode.G</param>
+ public abstract bool TargetFound(GraphNode node, uint H, uint G);
+ }
+
+ /// <summary>Ending condition which emulates the default one for the ABPath</summary>
+ public class ABPathEndingCondition : PathEndingCondition {
+ /// <summary>
+ /// Path which this ending condition is used on.
+ /// Same as <see cref="path"/> but downcasted to ABPath
+ /// </summary>
+ protected ABPath abPath;
+
+ public ABPathEndingCondition (ABPath p) {
+ if (p == null) throw new System.ArgumentNullException("p");
+ abPath = p;
+ path = p;
+ }
+
+ /// <summary>
+ /// Has the ending condition been fulfilled.
+ ///
+ /// This is per default the same as asking if node == p.endNode
+ /// </summary>
+ /// <param name="node">The current node.</param>
+ /// <param name="H">Heuristic score. See Pathfinding.PathNode.H</param>
+ /// <param name="G">Cost to reach this node. See Pathfinding.PathNode.G</param>
+ public override bool TargetFound (GraphNode node, uint H, uint G) {
+ return node == abPath.endNode;
+ }
+ }
+
+ /// <summary>Ending condition which stops a fixed distance from the target point</summary>
+ public class EndingConditionProximity : ABPathEndingCondition {
+ /// <summary>Maximum world distance to the target node before terminating the path</summary>
+ public float maxDistance = 10;
+
+ public EndingConditionProximity (ABPath p, float maxDistance) : base(p) {
+ this.maxDistance = maxDistance;
+ }
+
+ public override bool TargetFound (GraphNode node, uint H, uint G) {
+ return ((Vector3)node.position - abPath.originalEndPoint).sqrMagnitude <= maxDistance*maxDistance;
+ }
+ }
+}