astarclasses.cs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. // Empty namespace declaration to avoid errors in the free version
  4. // Which does not have any classes in the RVO namespace
  5. namespace Pathfinding.RVO {}
  6. namespace Pathfinding {
  7. using Pathfinding.Util;
  8. [System.Serializable]
  9. /// <summary>Stores editor colors</summary>
  10. public class AstarColor {
  11. public Color _SolidColor;
  12. public Color _UnwalkableNode;
  13. public Color _BoundsHandles;
  14. public Color _ConnectionLowLerp;
  15. public Color _ConnectionHighLerp;
  16. public Color _MeshEdgeColor;
  17. /// <summary>
  18. /// Holds user set area colors.
  19. /// Use GetAreaColor to get an area color
  20. /// </summary>
  21. public Color[] _AreaColors;
  22. public static Color SolidColor = new Color(30/255f, 102/255f, 201/255f, 0.9F);
  23. public static Color UnwalkableNode = new Color(1, 0, 0, 0.5F);
  24. public static Color BoundsHandles = new Color(0.29F, 0.454F, 0.741F, 0.9F);
  25. public static Color ConnectionLowLerp = new Color(0, 1, 0, 0.5F);
  26. public static Color ConnectionHighLerp = new Color(1, 0, 0, 0.5F);
  27. public static Color MeshEdgeColor = new Color(0, 0, 0, 0.5F);
  28. private static Color[] AreaColors = new Color[1];
  29. public static int ColorHash () {
  30. var hash = SolidColor.GetHashCode() ^ UnwalkableNode.GetHashCode() ^ BoundsHandles.GetHashCode() ^ ConnectionLowLerp.GetHashCode() ^ ConnectionHighLerp.GetHashCode() ^ MeshEdgeColor.GetHashCode();
  31. for (int i = 0; i < AreaColors.Length; i++) hash = 7*hash ^ AreaColors[i].GetHashCode();
  32. return hash;
  33. }
  34. /// <summary>
  35. /// Returns an color for an area, uses both user set ones and calculated.
  36. /// If the user has set a color for the area, it is used, but otherwise the color is calculated using AstarMath.IntToColor
  37. /// See: <see cref="RemappedAreaColors"/>
  38. /// </summary>
  39. public static Color GetAreaColor (uint area) {
  40. if (area >= AreaColors.Length) return AstarMath.IntToColor((int)area, 1F);
  41. return AreaColors[(int)area];
  42. }
  43. /// <summary>
  44. /// Returns an color for a tag, uses both user set ones and calculated.
  45. /// If the user has set a color for the tag, it is used, but otherwise the color is calculated using AstarMath.IntToColor
  46. /// See: <see cref="AreaColors"/>
  47. /// </summary>
  48. public static Color GetTagColor (uint tag) {
  49. if (tag >= AreaColors.Length) return AstarMath.IntToColor((int)tag, 1F);
  50. return AreaColors[(int)tag];
  51. }
  52. /// <summary>
  53. /// Pushes all local variables out to static ones.
  54. /// This is done because that makes it so much easier to access the colors during Gizmo rendering
  55. /// and it has a positive performance impact as well (gizmo rendering is hot code).
  56. /// It is a bit ugly though, but oh well.
  57. /// </summary>
  58. public void PushToStatic (AstarPath astar) {
  59. _AreaColors = _AreaColors ?? new Color[1];
  60. SolidColor = _SolidColor;
  61. UnwalkableNode = _UnwalkableNode;
  62. BoundsHandles = _BoundsHandles;
  63. ConnectionLowLerp = _ConnectionLowLerp;
  64. ConnectionHighLerp = _ConnectionHighLerp;
  65. MeshEdgeColor = _MeshEdgeColor;
  66. AreaColors = _AreaColors;
  67. }
  68. public AstarColor () {
  69. // Set default colors
  70. _SolidColor = new Color(30/255f, 102/255f, 201/255f, 0.9F);
  71. _UnwalkableNode = new Color(1, 0, 0, 0.5F);
  72. _BoundsHandles = new Color(0.29F, 0.454F, 0.741F, 0.9F);
  73. _ConnectionLowLerp = new Color(0, 1, 0, 0.5F);
  74. _ConnectionHighLerp = new Color(1, 0, 0, 0.5F);
  75. _MeshEdgeColor = new Color(0, 0, 0, 0.5F);
  76. }
  77. }
  78. /// <summary>
  79. /// Returned by graph ray- or linecasts containing info about the hit.
  80. /// This is the return value by the <see cref="Pathfinding.IRaycastableGraph.Linecast"/> methods.
  81. /// Some members will also be initialized even if nothing was hit, see the individual member descriptions for more info.
  82. ///
  83. /// [Open online documentation to see images]
  84. /// </summary>
  85. public struct GraphHitInfo {
  86. /// <summary>
  87. /// Start of the line/ray.
  88. /// Note that the point passed to the Linecast method will be clamped to the closest point on the navmesh.
  89. /// </summary>
  90. public Vector3 origin;
  91. /// <summary>
  92. /// Hit point.
  93. /// In case no obstacle was hit then this will be set to the endpoint of the line.
  94. /// </summary>
  95. public Vector3 point;
  96. /// <summary>
  97. /// Node which contained the edge which was hit.
  98. /// If the linecast did not hit anything then this will be set to the last node along the line's path (the one which contains the endpoint).
  99. ///
  100. /// For layered grid graphs the linecast will return true (i.e: no free line of sight) if when walking the graph we ended up at X,Z coordinate for the end node
  101. /// even if end node was on a different level (e.g the floor below or above in a building). In this case no node edge was really hit so this field will still be null.
  102. /// </summary>
  103. public GraphNode node;
  104. /// <summary>
  105. /// Where the tangent starts. <see cref="tangentOrigin"/> and <see cref="tangent"/> together actually describes the edge which was hit.
  106. /// [Open online documentation to see images]
  107. /// </summary>
  108. public Vector3 tangentOrigin;
  109. /// <summary>
  110. /// Tangent of the edge which was hit.
  111. /// [Open online documentation to see images]
  112. /// </summary>
  113. public Vector3 tangent;
  114. /// <summary>Distance from <see cref="origin"/> to <see cref="point"/></summary>
  115. public float distance {
  116. get {
  117. return (point-origin).magnitude;
  118. }
  119. }
  120. public GraphHitInfo (Vector3 point) {
  121. tangentOrigin = Vector3.zero;
  122. origin = Vector3.zero;
  123. this.point = point;
  124. node = null;
  125. tangent = Vector3.zero;
  126. }
  127. }
  128. /// <summary>Nearest node constraint. Constrains which nodes will be returned by the <see cref="AstarPath.GetNearest"/> function</summary>
  129. public class NNConstraint {
  130. /// <summary>
  131. /// Graphs treated as valid to search on.
  132. /// This is a bitmask meaning that bit 0 specifies whether or not the first graph in the graphs list should be able to be included in the search,
  133. /// bit 1 specifies whether or not the second graph should be included and so on.
  134. /// <code>
  135. /// // Enables the first and third graphs to be included, but not the rest
  136. /// myNNConstraint.graphMask = (1 << 0) | (1 << 2);
  137. /// </code>
  138. /// <code>
  139. /// GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph");
  140. /// GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph");
  141. ///
  142. /// NNConstraint nn = NNConstraint.Default;
  143. ///
  144. /// nn.graphMask = mask1 | mask2;
  145. ///
  146. /// // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph'
  147. /// var info = AstarPath.active.GetNearest(somePoint, nn);
  148. /// </code>
  149. ///
  150. /// Note: This does only affect which nodes are returned from a <see cref="AstarPath.GetNearest"/> call, if a valid graph is connected to an invalid graph using a node link then it might be searched anyway.
  151. ///
  152. /// See: <see cref="AstarPath.GetNearest"/>
  153. /// See: <see cref="SuitableGraph"/>
  154. /// See: bitmasks (view in online documentation for working links)
  155. /// </summary>
  156. public GraphMask graphMask = -1;
  157. /// <summary>Only treat nodes in the area <see cref="area"/> as suitable. Does not affect anything if <see cref="area"/> is less than 0 (zero)</summary>
  158. public bool constrainArea;
  159. /// <summary>Area ID to constrain to. Will not affect anything if less than 0 (zero) or if <see cref="constrainArea"/> is false</summary>
  160. public int area = -1;
  161. /// <summary>Constrain the search to only walkable or unwalkable nodes depending on <see cref="walkable"/>.</summary>
  162. public bool constrainWalkability = true;
  163. /// <summary>
  164. /// Only search for walkable or unwalkable nodes if <see cref="constrainWalkability"/> is enabled.
  165. /// If true, only walkable nodes will be searched for, otherwise only unwalkable nodes will be searched for.
  166. /// Does not affect anything if <see cref="constrainWalkability"/> if false.
  167. /// </summary>
  168. public bool walkable = true;
  169. /// <summary>
  170. /// if available, do an XZ check instead of checking on all axes.
  171. /// The navmesh/recast graph as well as the grid/layered grid graph supports this.
  172. ///
  173. /// This can be important on sloped surfaces. See the image below in which the closest point for each blue point is queried for:
  174. /// [Open online documentation to see images]
  175. ///
  176. /// The navmesh/recast graphs also contain a global option for this: <see cref="Pathfinding.NavmeshBase.nearestSearchOnlyXZ"/>.
  177. /// </summary>
  178. public bool distanceXZ;
  179. /// <summary>
  180. /// Sets if tags should be constrained.
  181. /// See: <see cref="tags"/>
  182. /// </summary>
  183. public bool constrainTags = true;
  184. /// <summary>
  185. /// Nodes which have any of these tags set are suitable.
  186. /// This is a bitmask, i.e bit 0 indicates that tag 0 is good, bit 3 indicates tag 3 is good etc.
  187. /// See: <see cref="constrainTags"/>
  188. /// See: <see cref="graphMask"/>
  189. /// See: bitmasks (view in online documentation for working links)
  190. /// </summary>
  191. public int tags = -1;
  192. /// <summary>
  193. /// Constrain distance to node.
  194. /// Uses distance from <see cref="AstarPath.maxNearestNodeDistance"/>.
  195. /// If this is false, it will completely ignore the distance limit.
  196. ///
  197. /// If there are no suitable nodes within the distance limit then the search will terminate with a null node as a result.
  198. /// Note: This value is not used in this class, it is used by the AstarPath.GetNearest function.
  199. /// </summary>
  200. public bool constrainDistance = true;
  201. /// <summary>
  202. /// Returns whether or not the graph conforms to this NNConstraint's rules.
  203. /// Note that only the first 31 graphs are considered using this function.
  204. /// If the <see cref="graphMask"/> has bit 31 set (i.e the last graph possible to fit in the mask), all graphs
  205. /// above index 31 will also be considered suitable.
  206. /// </summary>
  207. public virtual bool SuitableGraph (int graphIndex, NavGraph graph) {
  208. return graphMask.Contains(graphIndex);
  209. }
  210. /// <summary>Returns whether or not the node conforms to this NNConstraint's rules</summary>
  211. public virtual bool Suitable (GraphNode node) {
  212. if (constrainWalkability && node.Walkable != walkable) return false;
  213. if (constrainArea && area >= 0 && node.Area != area) return false;
  214. if (constrainTags && ((tags >> (int)node.Tag) & 0x1) == 0) return false;
  215. return true;
  216. }
  217. /// <summary>
  218. /// The default NNConstraint.
  219. /// Equivalent to new NNConstraint ().
  220. /// This NNConstraint has settings which works for most, it only finds walkable nodes
  221. /// and it constrains distance set by A* Inspector -> Settings -> Max Nearest Node Distance
  222. /// </summary>
  223. public static NNConstraint Default {
  224. get {
  225. return new NNConstraint();
  226. }
  227. }
  228. /// <summary>Returns a constraint which does not filter the results</summary>
  229. public static NNConstraint None {
  230. get {
  231. return new NNConstraint {
  232. constrainWalkability = false,
  233. constrainArea = false,
  234. constrainTags = false,
  235. constrainDistance = false,
  236. graphMask = -1,
  237. };
  238. }
  239. }
  240. /// <summary>Default constructor. Equals to the property <see cref="Default"/></summary>
  241. public NNConstraint () {
  242. }
  243. }
  244. /// <summary>
  245. /// A special NNConstraint which can use different logic for the start node and end node in a path.
  246. /// A PathNNConstraint can be assigned to the Path.nnConstraint field, the path will first search for the start node, then it will call <see cref="SetStart"/> and proceed with searching for the end node (nodes in the case of a MultiTargetPath).
  247. /// The default PathNNConstraint will constrain the end point to lie inside the same area as the start point.
  248. /// </summary>
  249. public class PathNNConstraint : NNConstraint {
  250. public static new PathNNConstraint Default {
  251. get {
  252. return new PathNNConstraint {
  253. constrainArea = true
  254. };
  255. }
  256. }
  257. /// <summary>Called after the start node has been found. This is used to get different search logic for the start and end nodes in a path</summary>
  258. public virtual void SetStart (GraphNode node) {
  259. if (node != null) {
  260. area = (int)node.Area;
  261. } else {
  262. constrainArea = false;
  263. }
  264. }
  265. }
  266. /// <summary>
  267. /// Internal result of a nearest node query.
  268. /// See: NNInfo
  269. /// </summary>
  270. public struct NNInfoInternal {
  271. /// <summary>
  272. /// Closest node found.
  273. /// This node is not necessarily accepted by any NNConstraint passed.
  274. /// See: constrainedNode
  275. /// </summary>
  276. public GraphNode node;
  277. /// <summary>
  278. /// Optional to be filled in.
  279. /// If the search will be able to find the constrained node without any extra effort it can fill it in.
  280. /// </summary>
  281. public GraphNode constrainedNode;
  282. /// <summary>The position clamped to the closest point on the <see cref="node"/>.</summary>
  283. public Vector3 clampedPosition;
  284. /// <summary>Clamped position for the optional constrainedNode</summary>
  285. public Vector3 constClampedPosition;
  286. public NNInfoInternal (GraphNode node) {
  287. this.node = node;
  288. constrainedNode = null;
  289. clampedPosition = Vector3.zero;
  290. constClampedPosition = Vector3.zero;
  291. UpdateInfo();
  292. }
  293. /// <summary>Updates <see cref="clampedPosition"/> and <see cref="constClampedPosition"/> from node positions</summary>
  294. public void UpdateInfo () {
  295. clampedPosition = node != null ? (Vector3)node.position : Vector3.zero;
  296. constClampedPosition = constrainedNode != null ? (Vector3)constrainedNode.position : Vector3.zero;
  297. }
  298. }
  299. /// <summary>Result of a nearest node query</summary>
  300. public struct NNInfo {
  301. /// <summary>Closest node</summary>
  302. public readonly GraphNode node;
  303. /// <summary>
  304. /// Closest point on the navmesh.
  305. /// This is the query position clamped to the closest point on the <see cref="node"/>.
  306. /// </summary>
  307. public readonly Vector3 position;
  308. /// <summary>
  309. /// Closest point on the navmesh.
  310. /// Deprecated: This field has been renamed to <see cref="position"/>
  311. /// </summary>
  312. [System.Obsolete("This field has been renamed to 'position'")]
  313. public Vector3 clampedPosition {
  314. get {
  315. return position;
  316. }
  317. }
  318. public NNInfo (NNInfoInternal internalInfo) {
  319. node = internalInfo.node;
  320. position = internalInfo.clampedPosition;
  321. }
  322. public static explicit operator Vector3(NNInfo ob) {
  323. return ob.position;
  324. }
  325. public static explicit operator GraphNode(NNInfo ob) {
  326. return ob.node;
  327. }
  328. }
  329. /// <summary>
  330. /// Progress info for e.g a progressbar.
  331. /// Used by the scan functions in the project
  332. /// See: <see cref="AstarPath.ScanAsync"/>
  333. /// </summary>
  334. public struct Progress {
  335. /// <summary>Current progress as a value between 0 and 1</summary>
  336. public readonly float progress;
  337. /// <summary>Description of what is currently being done</summary>
  338. public readonly string description;
  339. public Progress (float progress, string description) {
  340. this.progress = progress;
  341. this.description = description;
  342. }
  343. public Progress MapTo (float min, float max, string prefix = null) {
  344. return new Progress(Mathf.Lerp(min, max, progress), prefix + description);
  345. }
  346. public override string ToString () {
  347. return progress.ToString("0.0") + " " + description;
  348. }
  349. }
  350. /// <summary>Graphs which can be updated during runtime</summary>
  351. public interface IUpdatableGraph {
  352. /// <summary>
  353. /// Updates an area using the specified <see cref="GraphUpdateObject"/>.
  354. ///
  355. /// Notes to implementators.
  356. /// This function should (in order):
  357. /// -# Call o.WillUpdateNode on the GUO for every node it will update, it is important that this is called BEFORE any changes are made to the nodes.
  358. /// -# Update walkabilty using special settings such as the usePhysics flag used with the GridGraph.
  359. /// -# Call Apply on the GUO for every node which should be updated with the GUO.
  360. /// -# Update connectivity info if appropriate (GridGraphs updates connectivity, but most other graphs don't since then the connectivity cannot be recovered later).
  361. /// </summary>
  362. void UpdateArea(GraphUpdateObject o);
  363. /// <summary>
  364. /// May be called on the Unity thread before starting the update.
  365. /// See: CanUpdateAsync
  366. /// </summary>
  367. void UpdateAreaInit(GraphUpdateObject o);
  368. /// <summary>
  369. /// May be called on the Unity thread after executing the update.
  370. /// See: CanUpdateAsync
  371. /// </summary>
  372. void UpdateAreaPost(GraphUpdateObject o);
  373. GraphUpdateThreading CanUpdateAsync(GraphUpdateObject o);
  374. }
  375. /// <summary>Info about if a graph update has been applied or not</summary>
  376. public enum GraphUpdateStage {
  377. /// <summary>
  378. /// The graph update object has been created, but not used for anything yet.
  379. /// This is the default value.
  380. /// </summary>
  381. Created,
  382. /// <summary>The graph update has been sent to the pathfinding system and is scheduled to be applied to the graphs</summary>
  383. Pending,
  384. /// <summary>The graph update has been applied to all graphs</summary>
  385. Applied,
  386. /// <summary>
  387. /// The graph update has been aborted and will not be applied.
  388. /// This can happen if the AstarPath component is destroyed while a graph update is queued to be applied.
  389. /// </summary>
  390. Aborted,
  391. }
  392. /// <summary>
  393. /// Represents a collection of settings used to update nodes in a specific region of a graph.
  394. /// See: AstarPath.UpdateGraphs
  395. /// See: graph-updates (view in online documentation for working links)
  396. /// </summary>
  397. public class GraphUpdateObject {
  398. /// <summary>
  399. /// The bounds to update nodes within.
  400. /// Defined in world space.
  401. /// </summary>
  402. public Bounds bounds;
  403. /// <summary>
  404. /// Controlls if a flood fill will be carried out after this GUO has been applied.
  405. /// Disabling this can be used to gain a performance boost, but use with care.
  406. /// If you are sure that a GUO will not modify walkability or connections. You can set this to false.
  407. /// For example when only updating penalty values it can save processing power when setting this to false. Especially on large graphs.
  408. /// Note: If you set this to false, even though it does change e.g walkability, it can lead to paths returning that they failed even though there is a path,
  409. /// or the try to search the whole graph for a path even though there is none, and will in the processes use wast amounts of processing power.
  410. ///
  411. /// If using the basic GraphUpdateObject (not a derived class), a quick way to check if it is going to need a flood fill is to check if <see cref="modifyWalkability"/> is true or <see cref="updatePhysics"/> is true.
  412. ///
  413. /// Deprecated: Not necessary anymore
  414. /// </summary>
  415. [System.Obsolete("Not necessary anymore")]
  416. public bool requiresFloodFill { set {} }
  417. /// <summary>
  418. /// Use physics checks to update nodes.
  419. /// When updating a grid graph and this is true, the nodes' position and walkability will be updated using physics checks
  420. /// with settings from "Collision Testing" and "Height Testing".
  421. ///
  422. /// When updating a PointGraph, setting this to true will make it re-evaluate all connections in the graph which passes through the <see cref="bounds"/>.
  423. ///
  424. /// This has no effect when updating GridGraphs if <see cref="modifyWalkability"/> is turned on.
  425. /// You should not combine <see cref="updatePhysics"/> and <see cref="modifyWalkability"/>.
  426. ///
  427. /// On RecastGraphs, having this enabled will trigger a complete recalculation of all tiles intersecting the bounds.
  428. /// This is quite slow (but powerful). If you only want to update e.g penalty on existing nodes, leave it disabled.
  429. /// </summary>
  430. public bool updatePhysics = true;
  431. /// <summary>
  432. /// Reset penalties to their initial values when updating grid graphs and <see cref="updatePhysics"/> is true.
  433. /// If you want to keep old penalties even when you update the graph you may want to disable this option.
  434. ///
  435. /// The images below shows two overlapping graph update objects, the right one happened to be applied before the left one. They both have updatePhysics = true and are
  436. /// set to increase the penalty of the nodes by some amount.
  437. ///
  438. /// The first image shows the result when resetPenaltyOnPhysics is false. Both penalties are added correctly.
  439. /// [Open online documentation to see images]
  440. ///
  441. /// This second image shows when resetPenaltyOnPhysics is set to true. The first GUO is applied correctly, but then the second one (the left one) is applied
  442. /// and during its updating, it resets the penalties first and then adds penalty to the nodes. The result is that the penalties from both GUOs are not added together.
  443. /// The green patch in at the border is there because physics recalculation (recalculation of the position of the node, checking for obstacles etc.) affects a slightly larger
  444. /// area than the original GUO bounds because of the Grid Graph -> Collision Testing -> Diameter setting (it is enlarged by that value). So some extra nodes have their penalties reset.
  445. ///
  446. /// [Open online documentation to see images]
  447. /// </summary>
  448. public bool resetPenaltyOnPhysics = true;
  449. /// <summary>
  450. /// Update Erosion for GridGraphs.
  451. /// When enabled, erosion will be recalculated for grid graphs
  452. /// after the GUO has been applied.
  453. ///
  454. /// In the below image you can see the different effects you can get with the different values.
  455. /// The first image shows the graph when no GUO has been applied. The blue box is not identified as an obstacle by the graph, the reason
  456. /// there are unwalkable nodes around it is because there is a height difference (nodes are placed on top of the box) so erosion will be applied (an erosion value of 2 is used in this graph).
  457. /// The orange box is identified as an obstacle, so the area of unwalkable nodes around it is a bit larger since both erosion and collision has made
  458. /// nodes unwalkable.
  459. /// The GUO used simply sets walkability to true, i.e making all nodes walkable.
  460. ///
  461. /// [Open online documentation to see images]
  462. ///
  463. /// When updateErosion=True, the reason the blue box still has unwalkable nodes around it is because there is still a height difference
  464. /// so erosion will still be applied. The orange box on the other hand has no height difference and all nodes are set to walkable.
  465. ///
  466. /// When updateErosion=False, all nodes walkability are simply set to be walkable in this example.
  467. ///
  468. /// See: Pathfinding.GridGraph
  469. /// </summary>
  470. public bool updateErosion = true;
  471. /// <summary>
  472. /// NNConstraint to use.
  473. /// The Pathfinding.NNConstraint.SuitableGraph function will be called on the NNConstraint to enable filtering of which graphs to update.
  474. /// Note: As the Pathfinding.NNConstraint.SuitableGraph function is A* Pathfinding Project Pro only, this variable doesn't really affect anything in the free version.
  475. /// </summary>
  476. public NNConstraint nnConstraint = NNConstraint.None;
  477. /// <summary>
  478. /// Penalty to add to the nodes.
  479. /// A penalty of 1000 is equivalent to the cost of moving 1 world unit.
  480. /// </summary>
  481. public int addPenalty;
  482. /// <summary>
  483. /// If true, all nodes' walkable variable will be set to <see cref="setWalkability"/>.
  484. /// It is not recommended to combine this with <see cref="updatePhysics"/> since then you will just overwrite
  485. /// what <see cref="updatePhysics"/> calculated.
  486. /// </summary>
  487. public bool modifyWalkability;
  488. /// <summary>If <see cref="modifyWalkability"/> is true, the nodes' walkable variable will be set to this value</summary>
  489. public bool setWalkability;
  490. /// <summary>If true, all nodes' tag will be set to <see cref="setTag"/></summary>
  491. public bool modifyTag;
  492. /// <summary>If <see cref="modifyTag"/> is true, all nodes' tag will be set to this value</summary>
  493. public int setTag;
  494. /// <summary>
  495. /// Track which nodes are changed and save backup data.
  496. /// Used internally to revert changes if needed.
  497. /// </summary>
  498. public bool trackChangedNodes;
  499. /// <summary>
  500. /// Nodes which were updated by this GraphUpdateObject.
  501. /// Will only be filled if <see cref="trackChangedNodes"/> is true.
  502. /// Note: It might take a few frames for graph update objects to be applied.
  503. /// If you need this info immediately, use <see cref="AstarPath.FlushGraphUpdates"/>.
  504. /// </summary>
  505. public List<GraphNode> changedNodes;
  506. private List<uint> backupData;
  507. private List<Int3> backupPositionData;
  508. /// <summary>
  509. /// A shape can be specified if a bounds object does not give enough precision.
  510. /// Note that if you set this, you should set the bounds so that it encloses the shape
  511. /// because the bounds will be used as an initial fast check for which nodes that should
  512. /// be updated.
  513. /// </summary>
  514. public GraphUpdateShape shape;
  515. /// <summary>
  516. /// Info about if a graph update has been applied or not.
  517. /// Either an enum (see STAGE_CREATED and associated constants)
  518. /// or a non-negative count of the number of graphs that are waiting to apply this graph update.
  519. /// </summary>
  520. internal int internalStage = STAGE_CREATED;
  521. internal const int STAGE_CREATED = -1;
  522. internal const int STAGE_PENDING = -2;
  523. internal const int STAGE_ABORTED = -3;
  524. internal const int STAGE_APPLIED = 0;
  525. /// <summary>Info about if a graph update has been applied or not</summary>
  526. public GraphUpdateStage stage {
  527. get {
  528. switch (internalStage) {
  529. case STAGE_CREATED:
  530. return GraphUpdateStage.Created;
  531. case STAGE_APPLIED:
  532. return GraphUpdateStage.Applied;
  533. case STAGE_ABORTED:
  534. return GraphUpdateStage.Aborted;
  535. // Positive numbers means it is currently being applied, so it is also pending.
  536. default:
  537. case STAGE_PENDING:
  538. return GraphUpdateStage.Pending;
  539. }
  540. }
  541. }
  542. /// <summary>
  543. /// Should be called on every node which is updated with this GUO before it is updated.
  544. /// See: <see cref="trackChangedNodes"/>
  545. /// </summary>
  546. /// <param name="node">The node to save fields for. If null, nothing will be done</param>
  547. public virtual void WillUpdateNode (GraphNode node) {
  548. if (trackChangedNodes && node != null) {
  549. if (changedNodes == null) { changedNodes = ListPool<GraphNode>.Claim(); backupData = ListPool<uint>.Claim(); backupPositionData = ListPool<Int3>.Claim(); }
  550. changedNodes.Add(node);
  551. backupPositionData.Add(node.position);
  552. backupData.Add(node.Penalty);
  553. backupData.Add(node.Flags);
  554. #if !ASTAR_NO_GRID_GRAPH
  555. var gridNode = node as GridNode;
  556. if (gridNode != null) backupData.Add(gridNode.InternalGridFlags);
  557. #endif
  558. }
  559. }
  560. /// <summary>
  561. /// Reverts penalties and flags (which includes walkability) on every node which was updated using this GUO.
  562. /// Data for reversion is only saved if <see cref="trackChangedNodes"/> is true.
  563. ///
  564. /// Note: Not all data is saved. The saved data includes: penalties, walkability, tags, area, position and for grid graphs (not layered) it also includes connection data.
  565. ///
  566. /// This method modifies the graph. So it must be called inside while it is safe to modify the graph, for example inside a work item as shown in the example below.
  567. ///
  568. /// <code>
  569. /// // Update the graph
  570. /// var guo = new GraphUpdateObject(GetComponent<Collider>().bounds);
  571. ///
  572. /// guo.trackChangedNodes = true;
  573. /// AstarPath.active.UpdateGraphs(guo);
  574. /// // Apply the update immediately
  575. /// AstarPath.active.FlushGraphUpdates();
  576. ///
  577. /// // Then revert the change.
  578. /// // The reversion modifies the graph, so it must be done inside a work item
  579. /// AstarPath.active.AddWorkItem(() => {
  580. /// guo.RevertFromBackup();
  581. /// });
  582. /// // Apply the reversion immediately
  583. /// AstarPath.active.FlushWorkItems();
  584. /// </code>
  585. ///
  586. /// See: blocking (view in online documentation for working links)
  587. /// See: <see cref="Pathfinding.PathUtilities.UpdateGraphsNoBlock"/>
  588. /// </summary>
  589. public virtual void RevertFromBackup () {
  590. if (trackChangedNodes) {
  591. if (changedNodes == null) return;
  592. int counter = 0;
  593. for (int i = 0; i < changedNodes.Count; i++) {
  594. changedNodes[i].Penalty = backupData[counter];
  595. counter++;
  596. // Restore the flags, but not the HierarchicalNodeIndex as that could screw up some internal datastructures
  597. var tmp = changedNodes[i].HierarchicalNodeIndex;
  598. changedNodes[i].Flags = backupData[counter];
  599. changedNodes[i].HierarchicalNodeIndex = tmp;
  600. counter++;
  601. #if !ASTAR_NO_GRID_GRAPH
  602. var gridNode = changedNodes[i] as GridNode;
  603. if (gridNode != null) {
  604. gridNode.InternalGridFlags = (ushort)backupData[counter];
  605. counter++;
  606. }
  607. #endif
  608. changedNodes[i].position = backupPositionData[i];
  609. changedNodes[i].SetConnectivityDirty();
  610. }
  611. ListPool<GraphNode>.Release(ref changedNodes);
  612. ListPool<uint>.Release(ref backupData);
  613. ListPool<Int3>.Release(ref backupPositionData);
  614. } else {
  615. throw new System.InvalidOperationException("Changed nodes have not been tracked, cannot revert from backup. Please set trackChangedNodes to true before applying the update.");
  616. }
  617. }
  618. /// <summary>Updates the specified node using this GUO's settings</summary>
  619. public virtual void Apply (GraphNode node) {
  620. if (shape == null || shape.Contains(node)) {
  621. //Update penalty and walkability
  622. node.Penalty = (uint)(node.Penalty+addPenalty);
  623. if (modifyWalkability) {
  624. node.Walkable = setWalkability;
  625. }
  626. //Update tags
  627. if (modifyTag) node.Tag = (uint)setTag;
  628. }
  629. }
  630. public GraphUpdateObject () {
  631. }
  632. /// <summary>Creates a new GUO with the specified bounds</summary>
  633. public GraphUpdateObject (Bounds b) {
  634. bounds = b;
  635. }
  636. }
  637. /// <summary>Graph which has a well defined transformation from graph space to world space</summary>
  638. public interface ITransformedGraph {
  639. GraphTransform transform { get; }
  640. }
  641. /// <summary>Graph which supports the Linecast method</summary>
  642. public interface IRaycastableGraph {
  643. /// <summary>
  644. /// Checks if the straight line of sight between the two points on the graph is obstructed.
  645. ///
  646. /// Returns: True if an obstacle was hit, and false otherwise.
  647. /// </summary>
  648. /// <param name="start">The start point of the raycast.</param>
  649. /// <param name="end">The end point of the raycast.</param>
  650. bool Linecast(Vector3 start, Vector3 end);
  651. /// <summary>Deprecated:</summary>
  652. [System.Obsolete]
  653. bool Linecast(Vector3 start, Vector3 end, GraphNode hint);
  654. /// <summary>Deprecated:</summary>
  655. [System.Obsolete]
  656. bool Linecast(Vector3 start, Vector3 end, GraphNode hint, out GraphHitInfo hit);
  657. /// <summary>Deprecated:</summary>
  658. [System.Obsolete]
  659. bool Linecast(Vector3 start, Vector3 end, GraphNode hint, out GraphHitInfo hit, List<GraphNode> trace);
  660. /// <summary>
  661. /// Checks if the straight line of sight between the two points on the graph is obstructed.
  662. ///
  663. /// Returns: True if an obstacle was hit, and false otherwise.
  664. /// </summary>
  665. /// <param name="start">The start point of the raycast.</param>
  666. /// <param name="end">The end point of the raycast.</param>
  667. /// <param name="hit">Additional information about what was hit.</param>
  668. /// <param name="trace">If you supply a list, it will be filled with all nodes that the linecast traversed. You may pass null if you don't care about this.</param>
  669. /// <param name="filter">You may supply a callback to indicate which nodes should be considered unwalkable. Note that already unwalkable nodes cannot be made walkable in this way.</param>
  670. bool Linecast(Vector3 start, Vector3 end, out GraphHitInfo hit, List<GraphNode> trace = null, System.Func<GraphNode, bool> filter = null);
  671. }
  672. /// <summary>
  673. /// Integer Rectangle.
  674. /// Uses an inclusive coordinate range.
  675. ///
  676. /// Works almost like UnityEngine.Rect but with integer coordinates
  677. /// </summary>
  678. [System.Serializable]
  679. public struct IntRect {
  680. public int xmin, ymin, xmax, ymax;
  681. public IntRect (int xmin, int ymin, int xmax, int ymax) {
  682. this.xmin = xmin;
  683. this.xmax = xmax;
  684. this.ymin = ymin;
  685. this.ymax = ymax;
  686. }
  687. public bool Contains (int x, int y) {
  688. return !(x < xmin || y < ymin || x > xmax || y > ymax);
  689. }
  690. public Int2 Min {
  691. get {
  692. return new Int2(xmin, ymin);
  693. }
  694. }
  695. public Int2 Max {
  696. get {
  697. return new Int2(xmax, ymax);
  698. }
  699. }
  700. public int Width {
  701. get {
  702. return xmax-xmin+1;
  703. }
  704. }
  705. public int Height {
  706. get {
  707. return ymax-ymin+1;
  708. }
  709. }
  710. public int Area {
  711. get {
  712. return Width * Height;
  713. }
  714. }
  715. /// <summary>
  716. /// Returns if this rectangle is valid.
  717. /// An invalid rect could have e.g xmin > xmax.
  718. /// Rectamgles with a zero area area invalid.
  719. /// </summary>
  720. public bool IsValid () {
  721. return xmin <= xmax && ymin <= ymax;
  722. }
  723. public static bool operator == (IntRect a, IntRect b) {
  724. return a.xmin == b.xmin && a.xmax == b.xmax && a.ymin == b.ymin && a.ymax == b.ymax;
  725. }
  726. public static bool operator != (IntRect a, IntRect b) {
  727. return a.xmin != b.xmin || a.xmax != b.xmax || a.ymin != b.ymin || a.ymax != b.ymax;
  728. }
  729. public override bool Equals (System.Object obj) {
  730. var rect = (IntRect)obj;
  731. return xmin == rect.xmin && xmax == rect.xmax && ymin == rect.ymin && ymax == rect.ymax;
  732. }
  733. public override int GetHashCode () {
  734. return xmin*131071 ^ xmax*3571 ^ ymin*3109 ^ ymax*7;
  735. }
  736. /// <summary>
  737. /// Returns the intersection rect between the two rects.
  738. /// The intersection rect is the area which is inside both rects.
  739. /// If the rects do not have an intersection, an invalid rect is returned.
  740. /// See: IsValid
  741. /// </summary>
  742. public static IntRect Intersection (IntRect a, IntRect b) {
  743. return new IntRect(
  744. System.Math.Max(a.xmin, b.xmin),
  745. System.Math.Max(a.ymin, b.ymin),
  746. System.Math.Min(a.xmax, b.xmax),
  747. System.Math.Min(a.ymax, b.ymax)
  748. );
  749. }
  750. /// <summary>Returns if the two rectangles intersect each other</summary>
  751. public static bool Intersects (IntRect a, IntRect b) {
  752. return !(a.xmin > b.xmax || a.ymin > b.ymax || a.xmax < b.xmin || a.ymax < b.ymin);
  753. }
  754. /// <summary>
  755. /// Returns a new rect which contains both input rects.
  756. /// This rectangle may contain areas outside both input rects as well in some cases.
  757. /// </summary>
  758. public static IntRect Union (IntRect a, IntRect b) {
  759. return new IntRect(
  760. System.Math.Min(a.xmin, b.xmin),
  761. System.Math.Min(a.ymin, b.ymin),
  762. System.Math.Max(a.xmax, b.xmax),
  763. System.Math.Max(a.ymax, b.ymax)
  764. );
  765. }
  766. /// <summary>Returns a new IntRect which is expanded to contain the point</summary>
  767. public IntRect ExpandToContain (int x, int y) {
  768. return new IntRect(
  769. System.Math.Min(xmin, x),
  770. System.Math.Min(ymin, y),
  771. System.Math.Max(xmax, x),
  772. System.Math.Max(ymax, y)
  773. );
  774. }
  775. /// <summary>Returns a new rect which is expanded by range in all directions.</summary>
  776. /// <param name="range">How far to expand. Negative values are permitted.</param>
  777. public IntRect Expand (int range) {
  778. return new IntRect(xmin-range,
  779. ymin-range,
  780. xmax+range,
  781. ymax+range
  782. );
  783. }
  784. public override string ToString () {
  785. return "[x: "+xmin+"..."+xmax+", y: " + ymin +"..."+ymax+"]";
  786. }
  787. /// <summary>Draws some debug lines representing the rect</summary>
  788. public void DebugDraw (GraphTransform transform, Color color) {
  789. Vector3 p1 = transform.Transform(new Vector3(xmin, 0, ymin));
  790. Vector3 p2 = transform.Transform(new Vector3(xmin, 0, ymax));
  791. Vector3 p3 = transform.Transform(new Vector3(xmax, 0, ymax));
  792. Vector3 p4 = transform.Transform(new Vector3(xmax, 0, ymin));
  793. Debug.DrawLine(p1, p2, color);
  794. Debug.DrawLine(p2, p3, color);
  795. Debug.DrawLine(p3, p4, color);
  796. Debug.DrawLine(p4, p1, color);
  797. }
  798. }
  799. /// <summary>
  800. /// Holds a bitmask of graphs.
  801. /// This bitmask can hold up to 32 graphs.
  802. ///
  803. /// The bitmask can be converted to and from integers implicitly.
  804. ///
  805. /// <code>
  806. /// GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph");
  807. /// GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph");
  808. ///
  809. /// NNConstraint nn = NNConstraint.Default;
  810. ///
  811. /// nn.graphMask = mask1 | mask2;
  812. ///
  813. /// // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph'
  814. /// var info = AstarPath.active.GetNearest(somePoint, nn);
  815. /// </code>
  816. ///
  817. /// See: bitmasks (view in online documentation for working links)
  818. /// </summary>
  819. [System.Serializable]
  820. public struct GraphMask {
  821. /// <summary>Bitmask representing the mask</summary>
  822. public int value;
  823. /// <summary>A mask containing every graph</summary>
  824. public static GraphMask everything { get { return new GraphMask(-1); } }
  825. public GraphMask (int value) {
  826. this.value = value;
  827. }
  828. public static implicit operator int(GraphMask mask) {
  829. return mask.value;
  830. }
  831. public static implicit operator GraphMask (int mask) {
  832. return new GraphMask(mask);
  833. }
  834. /// <summary>Combines two masks to form the intersection between them</summary>
  835. public static GraphMask operator & (GraphMask lhs, GraphMask rhs) {
  836. return new GraphMask(lhs.value & rhs.value);
  837. }
  838. /// <summary>Combines two masks to form the union of them</summary>
  839. public static GraphMask operator | (GraphMask lhs, GraphMask rhs) {
  840. return new GraphMask(lhs.value | rhs.value);
  841. }
  842. /// <summary>Inverts the mask</summary>
  843. public static GraphMask operator ~ (GraphMask lhs) {
  844. return new GraphMask(~lhs.value);
  845. }
  846. /// <summary>True if this mask contains the graph with the given graph index</summary>
  847. public bool Contains (int graphIndex) {
  848. return ((value >> graphIndex) & 1) != 0;
  849. }
  850. /// <summary>A bitmask containing the given graph</summary>
  851. public static GraphMask FromGraph (NavGraph graph) {
  852. return 1 << (int)graph.graphIndex;
  853. }
  854. public override string ToString () {
  855. return value.ToString();
  856. }
  857. /// <summary>
  858. /// A bitmask containing the first graph with the given name.
  859. /// <code>
  860. /// GraphMask mask1 = GraphMask.FromGraphName("My Grid Graph");
  861. /// GraphMask mask2 = GraphMask.FromGraphName("My Other Grid Graph");
  862. ///
  863. /// NNConstraint nn = NNConstraint.Default;
  864. ///
  865. /// nn.graphMask = mask1 | mask2;
  866. ///
  867. /// // Find the node closest to somePoint which is either in 'My Grid Graph' OR in 'My Other Grid Graph'
  868. /// var info = AstarPath.active.GetNearest(somePoint, nn);
  869. /// </code>
  870. /// </summary>
  871. public static GraphMask FromGraphName (string graphName) {
  872. var graph = AstarData.active.data.FindGraph(g => g.name == graphName);
  873. if (graph == null) throw new System.ArgumentException("Could not find any graph with the name '" + graphName + "'");
  874. return FromGraph(graph);
  875. }
  876. }
  877. #region Delegates
  878. /// <summary>
  879. /// Delegate with on Path object as parameter.
  880. /// This is used for callbacks when a path has finished calculation.
  881. /// Example function:
  882. /// <code>
  883. /// public void Start () {
  884. /// // Assumes a Seeker component is attached to the GameObject
  885. /// Seeker seeker = GetComponent<Seeker>();
  886. ///
  887. /// // seeker.pathCallback is a OnPathDelegate, we add the function OnPathComplete to it so it will be called whenever a path has finished calculating on that seeker
  888. /// seeker.pathCallback += OnPathComplete;
  889. /// }
  890. ///
  891. /// public void OnPathComplete (Path p) {
  892. /// Debug.Log("This is called when a path is completed on the seeker attached to this GameObject");
  893. /// }
  894. /// </code>
  895. /// </summary>
  896. public delegate void OnPathDelegate(Path p);
  897. public delegate void OnGraphDelegate(NavGraph graph);
  898. public delegate void OnScanDelegate(AstarPath script);
  899. /// <summary>Deprecated:</summary>
  900. public delegate void OnScanStatus(Progress progress);
  901. #endregion
  902. #region Enums
  903. public enum GraphUpdateThreading {
  904. /// <summary>
  905. /// Call UpdateArea in the unity thread.
  906. /// This is the default value.
  907. /// Not compatible with SeparateThread.
  908. /// </summary>
  909. UnityThread = 0,
  910. /// <summary>Call UpdateArea in a separate thread. Not compatible with UnityThread.</summary>
  911. SeparateThread = 1 << 0,
  912. /// <summary>Calls UpdateAreaInit in the Unity thread before everything else</summary>
  913. UnityInit = 1 << 1,
  914. /// <summary>
  915. /// Calls UpdateAreaPost in the Unity thread after everything else.
  916. /// This is used together with SeparateThread to apply the result of the multithreaded
  917. /// calculations to the graph without modifying it at the same time as some other script
  918. /// might be using it (e.g calling GetNearest).
  919. /// </summary>
  920. UnityPost = 1 << 2,
  921. /// <summary>Combination of SeparateThread and UnityInit</summary>
  922. SeparateAndUnityInit = SeparateThread | UnityInit
  923. }
  924. /// <summary>How path results are logged by the system</summary>
  925. public enum PathLog {
  926. /// <summary>Does not log anything. This is recommended for release since logging path results has a performance overhead.</summary>
  927. None,
  928. /// <summary>Logs basic info about the paths</summary>
  929. Normal,
  930. /// <summary>Includes additional info</summary>
  931. Heavy,
  932. /// <summary>Same as heavy, but displays the info in-game using GUI</summary>
  933. InGame,
  934. /// <summary>Same as normal, but logs only paths which returned an error</summary>
  935. OnlyErrors
  936. }
  937. /// <summary>
  938. /// How to estimate the cost of moving to the destination during pathfinding.
  939. ///
  940. /// The heuristic is the estimated cost from the current node to the target.
  941. /// The different heuristics have roughly the same performance except not using any heuristic at all (<see cref="None)"/>
  942. /// which is usually significantly slower.
  943. ///
  944. /// In the image below you can see a comparison of the different heuristic options for an 8-connected grid and
  945. /// for a 4-connected grid.
  946. /// Note that all paths within the green area will all have the same length. The only difference between the heuristics
  947. /// is which of those paths of the same length that will be chosen.
  948. /// Note that while the Diagonal Manhattan and Manhattan options seem to behave very differently on an 8-connected grid
  949. /// they only do it in this case because of very small rounding errors. Usually they behave almost identically on 8-connected grids.
  950. ///
  951. /// [Open online documentation to see images]
  952. ///
  953. /// Generally for a 4-connected grid graph the Manhattan option should be used as it is the true distance on a 4-connected grid.
  954. /// For an 8-connected grid graph the Diagonal Manhattan option is the mathematically most correct option, however the Euclidean option
  955. /// is often preferred, especially if you are simplifying the path afterwards using modifiers.
  956. ///
  957. /// For any graph that is not grid based the Euclidean option is the best one to use.
  958. ///
  959. /// See: <a href="https://en.wikipedia.org/wiki/A*_search_algorithm">Wikipedia: A* search_algorithm</a>
  960. /// </summary>
  961. public enum Heuristic {
  962. /// <summary>Manhattan distance. See: https://en.wikipedia.org/wiki/Taxicab_geometry</summary>
  963. Manhattan,
  964. /// <summary>
  965. /// Manhattan distance, but allowing diagonal movement as well.
  966. /// Note: This option is currently hard coded for the XZ plane. It will be equivalent to Manhattan distance if you try to use it in the XY plane (i.e for a 2D game).
  967. /// </summary>
  968. DiagonalManhattan,
  969. /// <summary>Ordinary distance. See: https://en.wikipedia.org/wiki/Euclidean_distance</summary>
  970. Euclidean,
  971. /// <summary>
  972. /// Use no heuristic at all.
  973. /// This reduces the pathfinding algorithm to Dijkstra's algorithm.
  974. /// This is usually significantly slower compared to using a heuristic, which is why the A* algorithm is usually preferred over Dijkstra's algorithm.
  975. /// You may have to use this if you have a very non-standard graph. For example a world with a <a href="https://en.wikipedia.org/wiki/Wraparound_(video_games)">wraparound playfield</a> (think Civilization or Asteroids) and you have custom links
  976. /// with a zero cost from one end of the map to the other end. Usually the A* algorithm wouldn't find the wraparound links because it wouldn't think to look in that direction.
  977. /// See: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
  978. /// </summary>
  979. None
  980. }
  981. /// <summary>How to visualize the graphs in the editor</summary>
  982. public enum GraphDebugMode {
  983. /// <summary>Draw the graphs with a single solid color</summary>
  984. SolidColor,
  985. /// <summary>
  986. /// Use the G score of the last calculated paths to color the graph.
  987. /// The G score is the cost from the start node to the given node.
  988. /// See: https://en.wikipedia.org/wiki/A*_search_algorithm
  989. /// </summary>
  990. G,
  991. /// <summary>
  992. /// Use the H score (heuristic) of the last calculated paths to color the graph.
  993. /// The H score is the estimated cost from the current node to the target.
  994. /// See: https://en.wikipedia.org/wiki/A*_search_algorithm
  995. /// </summary>
  996. H,
  997. /// <summary>
  998. /// Use the F score of the last calculated paths to color the graph.
  999. /// The F score is the G score + the H score, or in other words the estimated cost total cost of the path.
  1000. /// See: https://en.wikipedia.org/wiki/A*_search_algorithm
  1001. /// </summary>
  1002. F,
  1003. /// <summary>
  1004. /// Use the penalty of each node to color the graph.
  1005. /// This does not show penalties added by tags.
  1006. /// See: graph-updates (view in online documentation for working links)
  1007. /// See: <see cref="Pathfinding.GraphNode.Penalty"/>
  1008. /// </summary>
  1009. Penalty,
  1010. /// <summary>
  1011. /// Visualize the connected components of the graph.
  1012. /// A node with a given color can reach any other node with the same color.
  1013. ///
  1014. /// See: <see cref="Pathfinding.HierarchicalGraph"/>
  1015. /// See: https://en.wikipedia.org/wiki/Connected_component_(graph_theory)
  1016. /// </summary>
  1017. Areas,
  1018. /// <summary>
  1019. /// Use the tag of each node to color the graph.
  1020. /// See: tags (view in online documentation for working links)
  1021. /// See: <see cref="Pathfinding.GraphNode.Tag"/>
  1022. /// </summary>
  1023. Tags,
  1024. /// <summary>
  1025. /// Visualize the hierarchical graph structure of the graph.
  1026. /// This is mostly for internal use.
  1027. /// See: <see cref="Pathfinding.HierarchicalGraph"/>
  1028. /// </summary>
  1029. HierarchicalNode,
  1030. }
  1031. /// <summary>Number of threads to use</summary>
  1032. public enum ThreadCount {
  1033. AutomaticLowLoad = -1,
  1034. AutomaticHighLoad = -2,
  1035. None = 0,
  1036. One = 1,
  1037. Two,
  1038. Three,
  1039. Four,
  1040. Five,
  1041. Six,
  1042. Seven,
  1043. Eight
  1044. }
  1045. /// <summary>Internal state of a path in the pipeline</summary>
  1046. public enum PathState {
  1047. Created = 0,
  1048. PathQueue = 1,
  1049. Processing = 2,
  1050. ReturnQueue = 3,
  1051. Returned = 4
  1052. }
  1053. /// <summary>State of a path request</summary>
  1054. public enum PathCompleteState {
  1055. /// <summary>
  1056. /// The path has not been calculated yet.
  1057. /// See: <see cref="Pathfinding.Path.IsDone()"/>
  1058. /// </summary>
  1059. NotCalculated = 0,
  1060. /// <summary>
  1061. /// The path calculation is done, but it failed.
  1062. /// See: <see cref="Pathfinding.Path.error"/>
  1063. /// </summary>
  1064. Error = 1,
  1065. /// <summary>The path has been successfully calculated</summary>
  1066. Complete = 2,
  1067. /// <summary>
  1068. /// The path has been calculated, but only a partial path could be found.
  1069. /// See: <see cref="Pathfinding.ABPath.calculatePartial"/>
  1070. /// </summary>
  1071. Partial = 3,
  1072. }
  1073. /// <summary>What to do when the character is close to the destination</summary>
  1074. public enum CloseToDestinationMode {
  1075. /// <summary>The character will stop as quickly as possible when within endReachedDistance (field that exist on most movement scripts) units from the destination</summary>
  1076. Stop,
  1077. /// <summary>The character will continue to the exact position of the destination</summary>
  1078. ContinueToExactDestination,
  1079. }
  1080. /// <summary>Indicates the side of a line that a point lies on</summary>
  1081. public enum Side : byte {
  1082. /// <summary>The point lies exactly on the line</summary>
  1083. Colinear = 0,
  1084. /// <summary>The point lies on the left side of the line</summary>
  1085. Left = 1,
  1086. /// <summary>The point lies on the right side of the line</summary>
  1087. Right = 2
  1088. }
  1089. public enum InspectorGridHexagonNodeSize {
  1090. /// <summary>Value is the distance between two opposing sides in the hexagon</summary>
  1091. Width,
  1092. /// <summary>Value is the distance between two opposing vertices in the hexagon</summary>
  1093. Diameter,
  1094. /// <summary>Value is the raw node size of the grid</summary>
  1095. NodeSize
  1096. }
  1097. public enum InspectorGridMode {
  1098. Grid,
  1099. IsometricGrid,
  1100. Hexagonal,
  1101. Advanced
  1102. }
  1103. /// <summary>
  1104. /// Determines which direction the agent moves in.
  1105. /// For 3D games you most likely want the ZAxisIsForward option as that is the convention for 3D games.
  1106. /// For 2D games you most likely want the YAxisIsForward option as that is the convention for 2D games.
  1107. /// </summary>
  1108. public enum OrientationMode {
  1109. ZAxisForward,
  1110. YAxisForward,
  1111. }
  1112. #endregion
  1113. }
  1114. namespace Pathfinding.Util {
  1115. /// <summary>Prevents code stripping. See: https://docs.unity3d.com/Manual/ManagedCodeStripping.html</summary>
  1116. public class PreserveAttribute : System.Attribute {
  1117. }
  1118. }