NavGraph.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. namespace PF {
  2. /** Exposes internal methods for graphs.
  3. * This is used to hide methods that should not be used by any user code
  4. * but still have to be 'public' or 'internal' (which is pretty much the same as 'public'
  5. * as this library is distributed with source code).
  6. *
  7. * Hiding the internal methods cleans up the documentation and IntelliSense suggestions.
  8. */
  9. public interface IGraphInternals {
  10. string SerializedEditorSettings { get; set; }
  11. void OnDestroy ();
  12. void DestroyAllNodes ();
  13. void SerializeExtraInfo (GraphSerializationContext ctx);
  14. void DeserializeExtraInfo (GraphSerializationContext ctx);
  15. void PostDeserialization (GraphSerializationContext ctx);
  16. void DeserializeSettingsCompatibility (GraphSerializationContext ctx);
  17. }
  18. /** Base class for all graphs */
  19. public abstract class NavGraph : IGraphInternals {
  20. /** Used as an ID of the graph, considered to be unique.
  21. * \note This is Pathfinding.Util.Guid not System.Guid. A replacement for System.Guid was coded for better compatibility with iOS
  22. */
  23. [JsonMember]
  24. public Guid guid;
  25. /** Default penalty to apply to all nodes */
  26. [JsonMember]
  27. public uint initialPenalty;
  28. /** Is the graph open in the editor */
  29. [JsonMember]
  30. public bool open;
  31. /** Index of the graph, used for identification purposes */
  32. public uint graphIndex;
  33. /** Name of the graph.
  34. * Can be set in the unity editor
  35. */
  36. [JsonMember]
  37. public string name;
  38. /** Enable to draw gizmos in the Unity scene view.
  39. * In the inspector this value corresponds to the state of
  40. * the 'eye' icon in the top left corner of every graph inspector.
  41. */
  42. [JsonMember]
  43. public bool drawGizmos = true;
  44. /** Used in the editor to check if the info screen is open.
  45. * Should be inside UNITY_EDITOR only \#ifs but just in case anyone tries to serialize a NavGraph instance using Unity, I have left it like this as it would otherwise cause a crash when building.
  46. * Version 3.0.8.1 was released because of this bug only
  47. */
  48. [JsonMember]
  49. public bool infoScreenOpen;
  50. /** Used in the Unity editor to store serialized settings for graph inspectors */
  51. [JsonMember]
  52. string serializedEditorSettings;
  53. /** Number of nodes in the graph.
  54. * Note that this is, unless the graph type has overriden it, an O(n) operation.
  55. *
  56. * This is an O(1) operation for grid graphs and point graphs.
  57. * For layered grid graphs it is an O(n) operation.
  58. */
  59. public virtual int CountNodes () {
  60. int count = 0;
  61. GetNodes(node => count++);
  62. return count;
  63. }
  64. /** Calls a delegate with all nodes in the graph until the delegate returns false */
  65. public void GetNodes (System.Func<GraphNode, bool> action) {
  66. bool cont = true;
  67. GetNodes(node => {
  68. if (cont) cont &= action(node);
  69. });
  70. }
  71. /** Calls a delegate with all nodes in the graph.
  72. * This is the primary way of iterating through all nodes in a graph.
  73. *
  74. * Do not change the graph structure inside the delegate.
  75. *
  76. * \snippet MiscSnippets.cs NavGraph.GetNodes1
  77. *
  78. * If you want to store all nodes in a list you can do this
  79. *
  80. * \snippet MiscSnippets.cs NavGraph.GetNodes2
  81. */
  82. public abstract void GetNodes (System.Action<GraphNode> action);
  83. /** Returns the nearest node to a position using the specified NNConstraint.
  84. * \param position The position to try to find a close node to
  85. * \param constraint Can for example tell the function to try to return a walkable node. If you do not get a good node back, consider calling GetNearestForce. */
  86. public NNInfoInternal GetNearest (Vector3 position, NNConstraint constraint) {
  87. return GetNearest(position, constraint, null);
  88. }
  89. /** Returns the nearest node to a position using the specified NNConstraint.
  90. * \param position The position to try to find a close node to
  91. * \param hint Can be passed to enable some graph generators to find the nearest node faster.
  92. * \param constraint Can for example tell the function to try to return a walkable node. If you do not get a good node back, consider calling GetNearestForce.
  93. */
  94. public virtual NNInfoInternal GetNearest (Vector3 position, NNConstraint constraint, GraphNode hint) {
  95. // This is a default implementation and it is pretty slow
  96. // Graphs usually override this to provide faster and more specialised implementations
  97. float maxDistSqr = constraint == null || constraint.constrainDistance ? PathFindHelper.GetConfig().maxNearestNodeDistanceSqr : float.PositiveInfinity;
  98. float minDist = float.PositiveInfinity;
  99. GraphNode minNode = null;
  100. float minConstDist = float.PositiveInfinity;
  101. GraphNode minConstNode = null;
  102. // Loop through all nodes and find the closest suitable node
  103. GetNodes(node => {
  104. float dist = (position-(Vector3)node.position).sqrMagnitude;
  105. if (dist < minDist) {
  106. minDist = dist;
  107. minNode = node;
  108. }
  109. if (dist < minConstDist && dist < maxDistSqr && (constraint == null || constraint.Suitable(node))) {
  110. minConstDist = dist;
  111. minConstNode = node;
  112. }
  113. });
  114. var nnInfo = new NNInfoInternal(minNode);
  115. nnInfo.constrainedNode = minConstNode;
  116. if (minConstNode != null) {
  117. nnInfo.constClampedPosition = (Vector3)minConstNode.position;
  118. } else if (minNode != null) {
  119. nnInfo.constrainedNode = minNode;
  120. nnInfo.constClampedPosition = (Vector3)minNode.position;
  121. }
  122. return nnInfo;
  123. }
  124. /**
  125. * Returns the nearest node to a position using the specified \link Pathfinding.NNConstraint constraint \endlink.
  126. * \returns an NNInfo. This method will only return an empty NNInfo if there are no nodes which comply with the specified constraint.
  127. */
  128. public virtual NNInfoInternal GetNearestForce (Vector3 position, NNConstraint constraint) {
  129. return GetNearest(position, constraint);
  130. }
  131. /** Function for cleaning up references.
  132. * This will be called on the same time as OnDisable on the gameObject which the AstarPath script is attached to (remember, not in the editor).
  133. * Use for any cleanup code such as cleaning up static variables which otherwise might prevent resources from being collected.
  134. * Use by creating a function overriding this one in a graph class, but always call base.OnDestroy () in that function.
  135. * All nodes should be destroyed in this function otherwise a memory leak will arise.
  136. */
  137. protected virtual void OnDestroy () {
  138. DestroyAllNodes();
  139. }
  140. /** Destroys all nodes in the graph.
  141. * \warning This is an internal method. Unless you have a very good reason, you should probably not call it.
  142. */
  143. protected virtual void DestroyAllNodes () {
  144. GetNodes(node => node.Destroy());
  145. }
  146. /** Serializes graph type specific node data.
  147. * This function can be overriden to serialize extra node information (or graph information for that matter)
  148. * which cannot be serialized using the standard serialization.
  149. * Serialize the data in any way you want and return a byte array.
  150. * When loading, the exact same byte array will be passed to the DeserializeExtraInfo function.\n
  151. * These functions will only be called if node serialization is enabled.\n
  152. */
  153. protected virtual void SerializeExtraInfo (GraphSerializationContext ctx) {
  154. }
  155. /** Deserializes graph type specific node data.
  156. * \see SerializeExtraInfo
  157. */
  158. protected virtual void DeserializeExtraInfo (GraphSerializationContext ctx) {
  159. }
  160. /** Called after all deserialization has been done for all graphs.
  161. * Can be used to set up more graph data which is not serialized
  162. */
  163. protected virtual void PostDeserialization (GraphSerializationContext ctx) {
  164. }
  165. /** An old format for serializing settings.
  166. * \deprecated This is deprecated now, but the deserialization code is kept to
  167. * avoid loosing data when upgrading from older versions.
  168. */
  169. protected virtual void DeserializeSettingsCompatibility (GraphSerializationContext ctx) {
  170. guid = new Guid(ctx.reader.ReadBytes(16));
  171. initialPenalty = ctx.reader.ReadUInt32();
  172. open = ctx.reader.ReadBoolean();
  173. name = ctx.reader.ReadString();
  174. drawGizmos = ctx.reader.ReadBoolean();
  175. infoScreenOpen = ctx.reader.ReadBoolean();
  176. }
  177. #region IGraphInternals implementation
  178. string IGraphInternals.SerializedEditorSettings { get { return serializedEditorSettings; } set { serializedEditorSettings = value; } }
  179. void IGraphInternals.OnDestroy () { OnDestroy(); }
  180. void IGraphInternals.DestroyAllNodes () { DestroyAllNodes(); }
  181. void IGraphInternals.SerializeExtraInfo (GraphSerializationContext ctx) { SerializeExtraInfo(ctx); }
  182. void IGraphInternals.DeserializeExtraInfo (GraphSerializationContext ctx) { DeserializeExtraInfo(ctx); }
  183. void IGraphInternals.PostDeserialization (GraphSerializationContext ctx) { PostDeserialization(ctx); }
  184. void IGraphInternals.DeserializeSettingsCompatibility (GraphSerializationContext ctx) { DeserializeSettingsCompatibility(ctx); }
  185. #endregion
  186. }
  187. }