/// Movement scripts should register to this delegate.
/// A temporary callback can also be set when calling StartPath, but that delegate will only be called for that path
///
/// <code>
/// public void Start () {
/// // Assumes a Seeker component is attached to the GameObject
/// Seeker seeker = GetComponent<Seeker>();
///
/// // seeker.pathCallback is a OnPathDelegate, we add the function OnPathComplete to it so it will be called whenever a path has finished calculating on that seeker
/// seeker.pathCallback += OnPathComplete;
/// }
///
/// public void OnPathComplete (Path p) {
/// Debug.Log("This is called when a path is completed on the seeker attached to this GameObject");
/// }
/// </code>
///
/// Deprecated: Pass a callback every time to the StartPath method instead, or use ai.SetPath+ai.pathPending on the movement script. You can cache it in your own script if you want to avoid the GC allocation of creating a new delegate.
/// </summary>
[System.Obsolete("Pass a callback every time to the StartPath method instead, or use ai.SetPath+ai.pathPending on the movement script. You can cache it in your own script if you want to avoid the GC allocation of creating a new delegate.")]
publicOnPathDelegatepathCallback;
/// <summary>Called before pathfinding is started</summary>
publicOnPathDelegatepreProcessPath;
/// <summary>Called after a path has been calculated, right before modifiers are executed.</summary>
publicOnPathDelegatepostProcessPath;
#ifUNITY_EDITOR
/// <summary>Used for drawing gizmos</summary>
[System.NonSerialized]
List<Vector3>lastCompletedVectorPath;
/// <summary>Used for drawing gizmos</summary>
[System.NonSerialized]
List<GraphNode>lastCompletedNodePath;
#endif
/// <summary>The current path</summary>
[System.NonSerialized]
protectedPathpath;
/// <summary>Previous path. Used to draw gizmos</summary>
[System.NonSerialized]
privatePathprevPath;
/// <summary>Cached delegate to avoid allocating one every time a path is started</summary>
privatereadonlyOnPathDelegateonPathDelegate;
/// <summary>Cached delegate to avoid allocating one every time a path is started</summary>
// This will send the path for post processing to modifiers attached to this Seeker
RunModifiers(ModifierPass.PostProcess,path);
}
if(sendCallbacks){
p.Claim(this);
#ifUNITY_EDITOR
lastCompletedNodePath=p.path;
lastCompletedVectorPath=p.vectorPath;
#endif
#pragmawarningdisable618
if(tmpPathCallback==null&&pathCallback==null){
#ifUNITY_EDITOR
// This checks for a common error that people make when they upgrade from an older version
// This will be removed in a future version to avoid the slight performance cost.
if(TryGetComponent<IAstarAI>(outvarai)){
Debug.LogWarning("A path was calculated, but no callback was specified when calling StartPath. If you wanted a movement script to use this path, use <b>ai.SetPath</b> instead of calling StartPath on the Seeker directly. The path will be forwarded to the attached movement script, but this behavior will be removed in the future.",this);
ai.SetPath(p);
}
#endif
}else{
// This will send the path to the callback (if any) specified when calling StartPath
if(tmpPathCallback!=null){
tmpPathCallback(p);
}
// This will send the path to any script which has registered to the callback
if(pathCallback!=null){
pathCallback(p);
}
}
#pragmawarningrestore618
// Note: it is important that #prevPath is kept alive (i.e. not pooled)
// if we are drawing gizmos.
// It is also important that #path is kept alive since it can be returned
// from the GetCurrentPath method.
// Since #path will be copied to #prevPath it is sufficient that #prevPath
// is kept alive until it is replaced.
// Recycle the previous path to reduce the load on the GC
if(prevPath!=null){
prevPath.Release(this,true);
}
prevPath=p;
}
}
/// <summary>
/// Called for each path in a MultiTargetPath.
/// Only post processes the path, does not return it.
/// </summary>
voidOnPartialPathComplete(Pathp){
OnPathComplete(p,true,false);
}
/// <summary>Called once for a MultiTargetPath. Only returns the path, does not post process.</summary>
voidOnMultiPathComplete(Pathp){
OnPathComplete(p,false,true);
}
/// <summary>
/// Queue a path to be calculated.
/// Since this method does not take a callback parameter, you should set the <see cref="pathCallback"/> field before calling this method.
///
/// <code>
/// void Start () {
/// // Get the seeker component attached to this GameObject
/// var seeker = GetComponent<Seeker>();
///
/// // Schedule a new path request from the current position to a position 10 units forward.
/// // When the path has been calculated, the OnPathComplete method will be called, unless it was canceled by another path request
/// <param name="start">The start point of the path</param>
/// <param name="end">The end point of the path</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// <param name="start">The start point of the path</param>
/// <param name="end">The end point of the path</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See #Pathfinding.NNConstraint.graphMask. This will override the #graphMask on this Seeker.</param>
/// Version: Since 4.1.x this method will no longer overwrite the graphMask on the path unless it is explicitly passed as a parameter (see other overloads of this method).
///
/// This overload takes no callback parameter. Instead, it is expected that you poll the path for completion, or block until it is completed.
///
/// See: <see cref="IsDone"/>
/// See: <see cref="Path.WaitForPath"/>
/// See: <see cref="Path.BlockUntilCalculated"/>
///
/// However, <see cref="Path.IsDone"/> should not be used with the Seeker component. This is because while the path itself may be calculated, the Seeker may not have had time to run post processing modifiers on the path yet.
/// </summary>
/// <param name="p">The path to start calculating</param>
publicPathStartPath(Pathp){
returnStartPath(p,null);
}
/// <summary>
/// Queue a path to be calculated.
///
/// The callback will be called when the path has been calculated (which may be several frames into the future).
/// The callback will not be called if a new path request is started before this path request has been calculated.
/// </summary>
/// <param name="p">The path to start calculating</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// The callback will be called when the path has been calculated (which may be several frames into the future).
/// The callback will not be called if a new path request is started before this path request has been calculated.
/// </summary>
/// <param name="p">The path to start calculating</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See \reflink{GraphMask}. This will override the #graphMask on this Seeker.</param>
path.FailWithError("Canceled path because a new one was requested.\n"+
"This happens when a new path is requested from the seeker when one was already being calculated.\n"+
"For example if a unit got a new order, you might request a new path directly instead of waiting for the now"+
" invalid path to be calculated. Which is probably what you want.\n"+
"If you are getting this a lot, you might want to consider how you are scheduling path requests.");
// No callback will be sent for the canceled path
}
// Set p as the active path
path=p;
tmpPathCallback=callback;
// Save the path id so we can make sure that if we cancel a path (see above) it should not have been recycled yet.
lastPathID=path.pathID;
// Pre process the path
RunModifiers(ModifierPass.PreProcess,path);
// Send the request to the pathfinder
AstarPath.StartPath(path);
}
/// <summary>
/// Starts a Multi Target Path from one start point to multiple end points.
/// A Multi Target Path will search for all the end points in one search and will return all paths if pathsForAll is true, or only the shortest one if pathsForAll is false.
///
/// callback will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
///
/// See: Pathfinding.MultiTargetPath
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
///
/// <code>
/// var endPoints = new Vector3[] {
/// transform.position + Vector3.forward * 5,
/// transform.position + Vector3.right * 10,
/// transform.position + Vector3.back * 15
/// };
/// // Start a multi target path, where endPoints is a Vector3[] array.
/// // The pathsForAll parameter specifies if a path to every end point should be searched for
/// // or if it should only try to find the shortest path to any end point.
/// var path = seeker.StartMultiTargetPath(transform.position, endPoints, pathsForAll: true, callback: null);
/// <param name="start">The start point of the path</param>
/// <param name="endPoints">The end points of the path</param>
/// <param name="pathsForAll">Indicates whether or not a path to all end points should be searched for or only to the closest one</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See Pathfinding.NNConstraint.graphMask. This will override the #graphMask on this Seeker.</param>
/// Starts a Multi Target Path from one start point to multiple end points.
/// A Multi Target Path will search for all the end points in one search and will return all paths if pathsForAll is true, or only the shortest one if pathsForAll is false.
///
/// callback will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
///
/// See: Pathfinding.MultiTargetPath
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
///
/// <code>
/// var endPoints = new Vector3[] {
/// transform.position + Vector3.forward * 5,
/// transform.position + Vector3.right * 10,
/// transform.position + Vector3.back * 15
/// };
/// // Start a multi target path, where endPoints is a Vector3[] array.
/// // The pathsForAll parameter specifies if a path to every end point should be searched for
/// // or if it should only try to find the shortest path to any end point.
/// var path = seeker.StartMultiTargetPath(transform.position, endPoints, pathsForAll: true, callback: null);
/// <param name="start">The start point of the path</param>
/// <param name="endPoints">The end points of the path</param>
/// <param name="pathsForAll">Indicates whether or not a path to all end points should be searched for or only to the closest one</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// Starts a Multi Target Path from multiple start points to a single target point.
/// A Multi Target Path will search from all start points to the target point in one search and will return all paths if pathsForAll is true, or only the shortest one if pathsForAll is false.
///
/// callback will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
///
/// See: Pathfinding.MultiTargetPath
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
/// </summary>
/// <param name="startPoints">The start points of the path</param>
/// <param name="end">The end point of the path</param>
/// <param name="pathsForAll">Indicates whether or not a path from all start points should be searched for or only to the closest one</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>
/// <param name="graphMask">Mask used to specify which graphs should be searched for close nodes. See Pathfinding.NNConstraint.graphMask. This will override the #graphMask on this Seeker.</param>
/// Starts a Multi Target Path from multiple start points to a single target point.
/// A Multi Target Path will search from all start points to the target point in one search and will return all paths if pathsForAll is true, or only the shortest one if pathsForAll is false.
///
/// callback will be called when the path has completed. Callback will not be called if the path is canceled (e.g when a new path is requested before the previous one has completed)
///
/// See: Pathfinding.MultiTargetPath
/// See: MultiTargetPathExample.cs (view in online documentation for working links) "Example of how to use multi-target-paths"
/// </summary>
/// <param name="startPoints">The start points of the path</param>
/// <param name="end">The end point of the path</param>
/// <param name="pathsForAll">Indicates whether or not a path from all start points should be searched for or only to the closest one</param>
/// <param name="callback">The function to call when the path has been calculated. If you don't want a callback (e.g. if you instead poll path.IsDone or use a similar method) you can set this to null.</param>