summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Modifiers/AlternativePath.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/Modifiers/AlternativePath.cs
parent3ba4020b69e5971bb0df7ee08b31d10ea4d01937 (diff)
+ astar project
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Modifiers/AlternativePath.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Modifiers/AlternativePath.cs94
1 files changed, 94 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Modifiers/AlternativePath.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Modifiers/AlternativePath.cs
new file mode 100644
index 0000000..16c9237
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Modifiers/AlternativePath.cs
@@ -0,0 +1,94 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+namespace Pathfinding {
+ [AddComponentMenu("Pathfinding/Modifiers/Alternative Path Modifier")]
+ [System.Serializable]
+ /// <summary>
+ /// Applies penalty to the paths it processes telling other units to avoid choosing the same path.
+ ///
+ /// Note that this might not work properly if penalties are modified by other actions as well (e.g graph update objects which reset the penalty to zero).
+ /// It will only work when all penalty modifications are relative, i.e adding or subtracting penalties, but not when setting penalties
+ /// to specific values.
+ ///
+ /// When destroyed, it will correctly remove any added penalty.
+ /// </summary>
+ [HelpURL("https://arongranberg.com/astar/documentation/stable/alternativepath.html")]
+ public class AlternativePath : MonoModifier {
+#if UNITY_EDITOR
+ [UnityEditor.MenuItem("CONTEXT/Seeker/Add Alternative Path Modifier")]
+ public static void AddComp (UnityEditor.MenuCommand command) {
+ (command.context as Component).gameObject.AddComponent(typeof(AlternativePath));
+ }
+#endif
+
+ public override int Order { get { return 10; } }
+
+ /// <summary>How much penalty (weight) to apply to nodes</summary>
+ public int penalty = 1000;
+
+ /// <summary>Max number of nodes to skip in a row</summary>
+ public int randomStep = 10;
+
+ /// <summary>The previous path</summary>
+ List<GraphNode> prevNodes = new List<GraphNode>();
+
+ /// <summary>The previous penalty used. Stored just in case it changes during operation</summary>
+ int prevPenalty;
+
+ /// <summary>A random object</summary>
+ readonly System.Random rnd = new System.Random();
+
+ bool destroyed;
+
+ public override void Apply (Path p) {
+ if (this == null) return;
+
+ ApplyNow(p.path);
+ }
+
+ protected void OnDestroy () {
+ destroyed = true;
+ ClearOnDestroy();
+ }
+
+ void ClearOnDestroy () {
+ InversePrevious();
+ }
+
+ void InversePrevious () {
+ // Remove previous penalty
+ if (prevNodes != null) {
+ bool warnPenalties = false;
+ for (int i = 0; i < prevNodes.Count; i++) {
+ if (prevNodes[i].Penalty < prevPenalty) {
+ warnPenalties = true;
+ prevNodes[i].Penalty = 0;
+ } else {
+ prevNodes[i].Penalty = (uint)(prevNodes[i].Penalty-prevPenalty);
+ }
+ }
+ if (warnPenalties) {
+ Debug.LogWarning("Penalty for some nodes has been reset while the AlternativePath modifier was active (possibly because of a graph update). Some penalties might be incorrect (they may be lower than expected for the affected nodes)");
+ }
+ }
+ }
+
+ void ApplyNow (List<GraphNode> nodes) {
+ InversePrevious();
+ prevNodes.Clear();
+
+ if (destroyed) return;
+
+ if (nodes != null) {
+ int rndStart = rnd.Next(randomStep);
+ for (int i = rndStart; i < nodes.Count; i += rnd.Next(1, randomStep)) {
+ nodes[i].Penalty = (uint)(nodes[i].Penalty+penalty);
+ prevNodes.Add(nodes[i]);
+ }
+ }
+
+ prevPenalty = penalty;
+ }
+ }
+}