From 8722a9920c1f6119bf6e769cba270e63097f8e25 Mon Sep 17 00:00:00 2001
From: chai <215380520@qq.com>
Date: Thu, 23 May 2024 10:08:29 +0800
Subject: + astar project
---
.../Core/Misc/AutoRepathPolicy.cs | 133 +++++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Misc/AutoRepathPolicy.cs
(limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Misc/AutoRepathPolicy.cs')
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Misc/AutoRepathPolicy.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Misc/AutoRepathPolicy.cs
new file mode 100644
index 0000000..78a211c
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Core/Misc/AutoRepathPolicy.cs
@@ -0,0 +1,133 @@
+using UnityEngine;
+using Unity.Mathematics;
+
+namespace Pathfinding {
+ using Pathfinding.Drawing;
+
+ ///
+ /// Policy for how often to recalculate an agent's path.
+ ///
+ /// See:
+ /// See:
+ ///
+ [System.Serializable]
+ public class AutoRepathPolicy {
+ /// Policy mode for how often to recalculate an agent's path.
+ public enum Mode {
+ ///
+ /// Never automatically recalculate the path.
+ /// Paths can be recalculated manually by for example calling or .
+ /// This mode is useful if you want full control of when the agent calculates its path.
+ ///
+ Never,
+ ///
+ /// Recalculate the path every seconds.
+ ///
+ /// This is primarily included for historical reasons, but might be useful if you want the path recalculations to happen at a very predictable rate.
+ /// In most cases it is recommended to use the Dynamic mode.
+ ///
+ EveryNSeconds,
+ ///
+ /// Recalculate the path at least every seconds but more often if the destination moves a lot.
+ /// This mode is recommended since it allows the agent to quickly respond to new destinations without using up a lot of CPU power to calculate paths
+ /// when it doesn't have to.
+ ///
+ /// More precisely:
+ /// Let C be a circle centered at the destination for the last calculated path, with a radius equal to the distance to that point divided by .
+ /// If the new destination is outside that circle the path will be immediately recalculated.
+ /// Otherwise let F be the 1 - (distance from the circle's center to the new destination divided by the circle's radius).
+ /// So F will be 1 if the new destination is the same as the old one and 0 if it is at the circle's edge.
+ /// Recalculate the path if the time since the last path recalculation is greater than multiplied by F.
+ ///
+ /// Thus if the destination doesn't change the path will be recalculated every seconds.
+ ///
+ Dynamic,
+ }
+
+ ///
+ /// Policy to use when recalculating paths.
+ ///
+ /// See: for more details.
+ ///
+ public Mode mode = Mode.Dynamic;
+
+ /// Number of seconds between each automatic path recalculation for Mode.EveryNSeconds
+ [UnityEngine.Serialization.FormerlySerializedAs("interval")]
+ public float period = 0.5f;
+
+ ///
+ /// How sensitive the agent should be to changes in its destination for Mode.Dynamic.
+ /// A higher value means the destination has to move less for the path to be recalculated.
+ ///
+ /// See:
+ ///
+ public float sensitivity = 10.0f;
+
+ /// Maximum number of seconds between each automatic path recalculation for Mode.Dynamic
+ [UnityEngine.Serialization.FormerlySerializedAs("maximumInterval")]
+ public float maximumPeriod = 2.0f;
+
+ /// If true the sensitivity will be visualized as a circle in the scene view when the game is playing
+ public bool visualizeSensitivity = false;
+
+ Vector3 lastDestination = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
+ float lastRepathTime = float.NegativeInfinity;
+
+ ///
+ /// True if the path should be recalculated according to the policy
+ ///
+ /// The above parameters are relevant only if is .
+ ///
+ /// The current position of the agent.
+ /// The radius of the agent. You may pass 0.0 if the agent doesn't have a radius.
+ /// The goal of the agent right now
+ /// The current time in seconds
+ public virtual bool ShouldRecalculatePath (Vector3 position, float radius, Vector3 destination, float time) {
+ if (mode == Mode.Never || float.IsPositiveInfinity(destination.x)) return false;
+
+ float timeSinceLast = time - lastRepathTime;
+ if (mode == Mode.EveryNSeconds) {
+ return timeSinceLast >= period;
+ } else {
+ // cost = change in destination / max(distance to destination, radius)
+ float squaredCost = (destination - lastDestination).sqrMagnitude / Mathf.Max((position - lastDestination).sqrMagnitude, radius*radius);
+ float fraction = squaredCost * (sensitivity*sensitivity);
+ if (float.IsNaN(fraction)) {
+ // The agent's radius is zero, and the destination is precisely at the agent's position, which is also the destination of the last calculated path
+ // This is a special case. It happens sometimes for the AILerp component when it reaches its
+ // destination, as the AILerp component has no radius.
+ // In this case we just use the maximum period.
+ fraction = 0;
+ }
+
+ return timeSinceLast >= maximumPeriod*(1 - Mathf.Sqrt(fraction));
+ }
+ }
+
+ /// Reset the runtime variables so that the policy behaves as if the game just started
+ public virtual void Reset () {
+ lastRepathTime = float.NegativeInfinity;
+ }
+
+ /// Must be called when a path request has been scheduled
+ public virtual void DidRecalculatePath (Vector3 destination, float time) {
+ lastRepathTime = time;
+ lastDestination = destination;
+ // Randomize the repath time slightly so that all agents don't request a path at the same time
+ // in the future. This is useful when there are a lot of agents instantiated at exactly the same time.
+ const float JITTER_AMOUNT = 0.3f;
+ lastRepathTime -= (UnityEngine.Random.value - 0.5f) * JITTER_AMOUNT * (mode == Mode.Dynamic ? maximumPeriod : period);
+ }
+
+ public void DrawGizmos (CommandBuilder draw, Vector3 position, float radius, Util.NativeMovementPlane movementPlane) {
+ if (visualizeSensitivity && !float.IsPositiveInfinity(lastDestination.x)) {
+ float r = Mathf.Sqrt(Mathf.Max((position - lastDestination).sqrMagnitude, radius*radius)/(sensitivity*sensitivity));
+ draw.Circle(lastDestination, movementPlane.ToWorld(float2.zero, 1), r, Color.magenta);
+ }
+ }
+
+ public AutoRepathPolicy Clone () {
+ return MemberwiseClone() as AutoRepathPolicy;
+ }
+ }
+}
--
cgit v1.1-26-g67d0