NN.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using UnityEngine;
  2. namespace PF
  3. {
  4. /** Nearest node constraint. Constrains which nodes will be returned by the \link AstarPath.GetNearest GetNearest\endlink function */
  5. public class NNConstraint {
  6. /** Graphs treated as valid to search on.
  7. * 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,
  8. * bit 1 specifies whether or not the second graph should be included and so on.
  9. * \code
  10. * // Enables the first and third graphs to be included, but not the rest
  11. * myNNConstraint.graphMask = (1 << 0) | (1 << 2);
  12. * \endcode
  13. * \note This does only affect which nodes are returned from a \link AstarPath.GetNearest GetNearest\endlink call, if a valid graph is connected to an invalid graph using a node link then it might be searched anyway.
  14. *
  15. * \see #AstarPath.GetNearest
  16. * \see #SuitableGraph
  17. * \see \ref bitmasks
  18. */
  19. public int graphMask = -1;
  20. /** Only treat nodes in the area #area as suitable. Does not affect anything if #area is less than 0 (zero) */
  21. public bool constrainArea;
  22. /** Area ID to constrain to. Will not affect anything if less than 0 (zero) or if #constrainArea is false */
  23. public int area = -1;
  24. /** Constrain the search to only walkable or unwalkable nodes depending on #walkable. */
  25. public bool constrainWalkability = true;
  26. /** Only search for walkable or unwalkable nodes if #constrainWalkability is enabled.
  27. * If true, only walkable nodes will be searched for, otherwise only unwalkable nodes will be searched for.
  28. * Does not affect anything if #constrainWalkability if false.
  29. */
  30. public bool walkable = true;
  31. /** if available, do an XZ check instead of checking on all axes.
  32. * The navmesh/recast graph supports this.
  33. *
  34. * This can be important on sloped surfaces. See the image below in which the closest point for each blue point is queried for:
  35. * \shadowimage{distanceXZ2.png}
  36. *
  37. * The navmesh/recast graphs also contain a global option for this: \link Pathfinding.NavmeshBase.nearestSearchOnlyXZ nearestSearchOnlyXZ\endlink.
  38. */
  39. public bool distanceXZ;
  40. /** Sets if tags should be constrained.
  41. * \see #tags
  42. */
  43. public bool constrainTags = true;
  44. /** Nodes which have any of these tags set are suitable.
  45. * This is a bitmask, i.e bit 0 indicates that tag 0 is good, bit 3 indicates tag 3 is good etc.
  46. * \see #constrainTags
  47. * \see #graphMask
  48. * \see \ref bitmasks
  49. */
  50. public int tags = -1;
  51. /** Constrain distance to node.
  52. * Uses distance from #AstarPath.maxNearestNodeDistance.
  53. * If this is false, it will completely ignore the distance limit.
  54. *
  55. * If there are no suitable nodes within the distance limit then the search will terminate with a null node as a result.
  56. * \note This value is not used in this class, it is used by the AstarPath.GetNearest function.
  57. */
  58. public bool constrainDistance = true;
  59. /** Returns whether or not the graph conforms to this NNConstraint's rules.
  60. * Note that only the first 31 graphs are considered using this function.
  61. * If the #graphMask has bit 31 set (i.e the last graph possible to fit in the mask), all graphs
  62. * above index 31 will also be considered suitable.
  63. */
  64. public virtual bool SuitableGraph (int graphIndex, NavGraph graph) {
  65. return ((graphMask >> graphIndex) & 1) != 0;
  66. }
  67. /** Returns whether or not the node conforms to this NNConstraint's rules */
  68. public virtual bool Suitable (GraphNode node) {
  69. if (constrainWalkability && node.Walkable != walkable) return false;
  70. if (constrainArea && area >= 0 && node.Area != area) return false;
  71. if (constrainTags && ((tags >> (int)node.Tag) & 0x1) == 0) return false;
  72. return true;
  73. }
  74. /** The default NNConstraint.
  75. * Equivalent to new NNConstraint ().
  76. * This NNConstraint has settings which works for most, it only finds walkable nodes
  77. * and it constrains distance set by A* Inspector -> Settings -> Max Nearest Node Distance */
  78. public static NNConstraint Default {
  79. get {
  80. return new NNConstraint();
  81. }
  82. }
  83. /** Returns a constraint which does not filter the results */
  84. public static NNConstraint None {
  85. get {
  86. return new NNConstraint {
  87. constrainWalkability = false,
  88. constrainArea = false,
  89. constrainTags = false,
  90. constrainDistance = false,
  91. graphMask = -1,
  92. };
  93. }
  94. }
  95. /** Default constructor. Equals to the property #Default */
  96. public NNConstraint () {
  97. }
  98. }
  99. /** A special NNConstraint which can use different logic for the start node and end node in a path.
  100. * A PathNNConstraint can be assigned to the Path.nnConstraint field, the path will first search for the start node, then it will call #SetStart and proceed with searching for the end node (nodes in the case of a MultiTargetPath).\n
  101. * The default PathNNConstraint will constrain the end point to lie inside the same area as the start point.
  102. */
  103. public class PathNNConstraint : NNConstraint {
  104. public static new PathNNConstraint Default {
  105. get {
  106. return new PathNNConstraint {
  107. constrainArea = true
  108. };
  109. }
  110. }
  111. /** 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 */
  112. public virtual void SetStart (GraphNode node) {
  113. if (node != null) {
  114. area = (int)node.Area;
  115. } else {
  116. constrainArea = false;
  117. }
  118. }
  119. }
  120. /** Internal result of a nearest node query.
  121. * \see NNInfo
  122. */
  123. public struct NNInfoInternal {
  124. /** Closest node found.
  125. * This node is not necessarily accepted by any NNConstraint passed.
  126. * \see constrainedNode
  127. */
  128. public GraphNode node;
  129. /** Optional to be filled in.
  130. * If the search will be able to find the constrained node without any extra effort it can fill it in. */
  131. public GraphNode constrainedNode;
  132. /** The position clamped to the closest point on the #node.
  133. */
  134. public Vector3 clampedPosition;
  135. /** Clamped position for the optional constrainedNode */
  136. public Vector3 constClampedPosition;
  137. public NNInfoInternal (GraphNode node) {
  138. this.node = node;
  139. constrainedNode = null;
  140. clampedPosition = Vector3.zero;
  141. constClampedPosition = Vector3.zero;
  142. UpdateInfo();
  143. }
  144. /** Updates #clampedPosition and #constClampedPosition from node positions */
  145. public void UpdateInfo () {
  146. clampedPosition = node != null ? (Vector3)node.position : Vector3.zero;
  147. constClampedPosition = constrainedNode != null ? (Vector3)constrainedNode.position : Vector3.zero;
  148. }
  149. }
  150. /** Result of a nearest node query */
  151. public struct NNInfo {
  152. /** Closest node */
  153. public readonly GraphNode node;
  154. /** Closest point on the navmesh.
  155. * This is the query position clamped to the closest point on the #node.
  156. */
  157. public readonly Vector3 position;
  158. /** Closest point on the navmesh.
  159. * \deprecated This field has been renamed to #position
  160. */
  161. [System.Obsolete("This field has been renamed to 'position'")]
  162. public Vector3 clampedPosition {
  163. get {
  164. return position;
  165. }
  166. }
  167. public NNInfo (NNInfoInternal internalInfo) {
  168. node = internalInfo.node;
  169. position = internalInfo.clampedPosition;
  170. }
  171. public static explicit operator Vector3 (NNInfo ob) {
  172. return ob.position;
  173. }
  174. public static explicit operator GraphNode (NNInfo ob) {
  175. return ob.node;
  176. }
  177. }
  178. }