/// The point graph is the most basic graph structure, it consists of a number of interconnected points in space called nodes or waypoints.
/// The point graph takes a Transform object as "root", this Transform will be searched for child objects, every child object will be treated as a node.
/// If <see cref="recursive"/> is enabled, it will also search the child objects of the children recursively.
/// It will then check if any connections between the nodes can be made, first it will check if the distance between the nodes isn't too large (<see cref="maxDistance)"/>
/// and then it will check if the axis aligned distance isn't too high. The axis aligned distance, named <see cref="limits"/>,
/// is useful because usually an AI cannot climb very high, but linking nodes far away from each other,
/// but on the same Y level should still be possible. <see cref="limits"/> and <see cref="maxDistance"/> are treated as being set to infinity if they are set to 0 (zero).
/// Lastly it will check if there are any obstructions between the nodes using
/// <a href="http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html">raycasting</a> which can optionally be thick.
/// One thing to think about when using raycasting is to either place the nodes a small
/// distance above the ground in your scene or to make sure that the ground is not in the raycast mask to avoid the raycast from hitting the ground.
///
/// Alternatively, a tag can be used to search for nodes.
/// See: http://docs.unity3d.com/Manual/Tags.html
///
/// For larger graphs, it can take quite some time to scan the graph with the default settings.
/// If you have the pro version you can enable <see cref="optimizeForSparseGraph"/> which will in most cases reduce the calculation times
/// drastically.
///
/// Note: Does not support linecast because of obvious reasons.
///
/// [Open online documentation to see images]
/// [Open online documentation to see images]
/// </summary>
[JsonOptIn]
[Pathfinding.Util.Preserve]
publicclassPointGraph:NavGraph
,IUpdatableGraph{
/// <summary>Childs of this transform are treated as nodes</summary>
[JsonMember]
publicTransformroot;
/// <summary>If no <see cref="root"/> is set, all nodes with the tag is used as nodes</summary>
[JsonMember]
publicstringsearchTag;
/// <summary>
/// Max distance for a connection to be valid.
/// The value 0 (zero) will be read as infinity and thus all nodes not restricted by
/// other constraints will be added as connections.
///
/// A negative value will disable any neighbours to be added.
/// It will completely stop the connection processing to be done, so it can save you processing
/// power if you don't these connections.
/// </summary>
[JsonMember]
publicfloatmaxDistance;
/// <summary>Max distance along the axis for a connection to be valid. 0 = infinity</summary>
[JsonMember]
publicVector3limits;
/// <summary>Use raycasts to check connections</summary>
[JsonMember]
publicboolraycast=true;
/// <summary>Use the 2D Physics API</summary>
[JsonMember]
publicbooluse2DPhysics;
/// <summary>Use thick raycast</summary>
[JsonMember]
publicboolthickRaycast;
/// <summary>Thick raycast radius</summary>
[JsonMember]
publicfloatthickRaycastRadius=1;
/// <summary>Recursively search for child nodes to the <see cref="root"/></summary>
[JsonMember]
publicboolrecursive=true;
/// <summary>Layer mask to use for raycast</summary>
[JsonMember]
publicLayerMaskmask;
/// <summary>
/// Optimizes the graph for sparse graphs.
///
/// This can reduce calculation times for both scanning and for normal path requests by huge amounts.
/// It reduces the number of node-node checks that need to be done during scan, and can also optimize getting the nearest node from the graph (such as when querying for a path).
///
/// Try enabling and disabling this option, check the scan times logged when you scan the graph to see if your graph is suited for this optimization
/// or if it makes it slower.
///
/// The gain of using this optimization increases with larger graphs, the default scan algorithm is brute force and requires O(n^2) checks, this optimization
/// along with a graph suited for it, requires only O(n) checks during scan (assuming the connection distance limits are reasonable).
///
/// Warning:
/// When you have this enabled, you will not be able to move nodes around using scripting unless you recalculate the lookup structure at the same time.
/// See: <see cref="RebuildNodeLookup"/>
///
/// If you enable this during runtime, you will need to call <see cref="RebuildNodeLookup"/> to make sure any existing nodes are added to the lookup structure.
/// If the graph doesn't have any nodes yet or if you are going to scan the graph afterwards then you do not need to do this.
/// </summary>
[JsonMember]
publicbooloptimizeForSparseGraph;
PointKDTreelookupTree=newPointKDTree();
/// <summary>
/// Longest known connection.
/// In squared Int3 units.
///
/// See: <see cref="RegisterConnectionLength"/>
/// </summary>
longmaximumConnectionLength=0;
/// <summary>
/// All nodes in this graph.
/// Note that only the first <see cref="nodeCount"/> will be non-null.
///
/// You can also use the GetNodes method to get all nodes.
/// If you enable this during runtime, you will need to call <see cref="RebuildConnectionDistanceLookup"/> to make sure some cache data is properly recalculated.
/// If the graph doesn't have any nodes yet or if you are going to scan the graph afterwards then you do not need to do this.
/// </summary>
[JsonMember]
publicNodeDistanceModenearestNodeDistanceMode;
/// <summary>Number of nodes in this graph</summary>
/// In the image above there are a few red nodes. Assume the agent is the orange circle. Using the Node mode the closest point on the graph that would be found would be the node at the bottom center which
/// may not be what you want. Using the Connection mode it will find the closest point on the connection between the two nodes in the top half of the image.
///
/// When using the Connection option you may also want to use the Connection option for the Seeker's Start End Modifier snapping options.
/// This is not strictly necessary, but it most cases it is what you want.
/// All nearest node queries find the closest node center.
/// This is the fastest option but it may not be what you want if you have long connections.
/// </summary>
Node,
/// <summary>
/// All nearest node queries find the closest point on edges between nodes.
/// This is useful if you have long connections where the agent might be closer to some unrelated node if it is standing on a long connection between two nodes.
/// This mode is however slower than the Node mode.
/// Ensures the graph knows that there is a connection with this length.
/// This is used when the nearest node distance mode is set to ToConnection.
/// If you are modifying node connections yourself (i.e. manipulating the PointNode.connections array) then you must call this function
/// when you add any connections.
///
/// When using PointNode.AddConnection this is done automatically.
/// It is also done for all nodes when <see cref="RebuildNodeLookup"/> is called.
/// </summary>
/// <param name="sqrLength">The length of the connection in squared Int3 units. This can be calculated using (node1.position - node2.position).sqrMagnitudeLong.</param>
/// Recalculates connections for all nodes in the graph.
/// This is useful if you have created nodes manually using <see cref="AddNode"/> and then want to connect them in the same way as the point graph normally connects nodes.
/// </summary>
publicvoidConnectNodes(){
varie=ConnectNodesAsync().GetEnumerator();
while(ie.MoveNext()){}
RebuildConnectionDistanceLookup();
}
/// <summary>
/// Calculates connections for all nodes in the graph.
/// This is an IEnumerable, you can iterate through it using e.g foreach to get progress information.
/// </summary>
IEnumerable<Progress>ConnectNodesAsync(){
if(maxDistance>=0){
// To avoid too many allocations, these lists are reused for each node
varconnections=newList<Connection>();
varcandidateConnections=newList<GraphNode>();
longmaxSquaredRange;
// Max possible squared length of a connection between two nodes
// This is used to speed up the calculations by skipping a lot of nodes that do not need to be checked