astarclasses.cs 43 KB

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