NN.cs 7.2 KB

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