/// Moves a grid or recast graph to follow a target.
///
/// This is useful if you have a very large, or even infinite, world, but pathfinding is only necessary in a small region around an object (for example the player).
/// This component will move a graph around so that its center stays close to the <see cref="target"/> object.
///
/// Note: This component can only be used with grid graphs, layered grid graphs and (tiled) recast graphs.
///
/// <b>Usage</b>
/// Take a look at the example scene called "Procedural" for an example of how to use this script
///
/// Attach this to some object in the scene and assign the target to e.g the player.
/// Then the graph will follow that object around as it moves.
///
/// [Open online documentation to see videos]
///
/// [Open online documentation to see videos]
///
/// <b>Performance</b>
/// When the graph is moved you may notice an fps drop.
/// If this grows too large you can try a few things:
///
/// General advice:
/// - Turn on multithreading (A* Inspector -> Settings)
/// - Make sure you have 'Show Graphs' disabled in the A* inspector, since gizmos in the scene view can take some
/// time to update when the graph moves, and thus make it seem like this script is slower than it actually is.
///
/// For grid graphs:
/// - Avoid using any erosion in the grid graph settings. This is relatively slow. Each erosion iteration requires expanding the region that is updated by 1 node.
/// - Reduce the grid size or resolution.
/// - Reduce the <see cref="updateDistance"/>. This will make the updates smaller but more frequent.
/// This only works to some degree however since an update has an inherent overhead.
/// - Disable Height Testing or Collision Testing in the grid graph if you can. This can give a performance boost
/// since fewer calls to the physics engine need to be done.
///
/// For recast graphs:
/// - Rasterize colliders instead of meshes. This is typically faster.
/// - Use a reasonable tile size. Very small tiles can cause more overhead, and too large tiles might mean that you are updating too much in one go.
/// Typical values are around 64 to 256 voxels.
/// - Use a larger cell size. A lower cell size will give better quality graphs, but it will also be slower to scan.
///
/// The graph updates will be offloaded to worker threads as much as possible.
///
/// See: large-worlds (view in online documentation for working links)
/// Grid graphs will be updated if the target is more than this number of nodes from the graph center.
/// Note that this is in nodes, not world units.
///
/// Note: For recast graphs, this setting has no effect.
/// </summary>
publicfloatupdateDistance=10;
/// <summary>Graph will be moved to follow this target</summary>
publicTransformtarget;
/// <summary>True while the graph is being updated by this script</summary>
publicboolupdatingGraph{get;privateset;}
/// <summary>
/// Graph to update.
/// This will be set at Start based on <see cref="graphIndex"/>.
/// During runtime you may set this to any graph or to null to disable updates.
/// </summary>
publicNavGraphgraph;
/// <summary>
/// Index for the graph to update.
/// This will be used at Start to set <see cref="graph"/>.
///
/// This is an index into the AstarPath.active.data.graphs array.
/// </summary>
[HideInInspector]
publicintgraphIndex;
voidStart(){
if(AstarPath.active==null)thrownewSystem.Exception("There is no AstarPath object in the scene");
// If one creates this component via a script then they may have already set the graph field.
// In that case don't replace it.
if(graph==null){
if(graphIndex<0)thrownewSystem.Exception("Graph index should not be negative");
if(graphIndex>=AstarPath.active.data.graphs.Length)thrownewSystem.Exception("The ProceduralGraphMover was configured to use graph index "+graphIndex+", but only "+AstarPath.active.data.graphs.Length+" graphs exist");
graph=AstarPath.active.data.graphs[graphIndex];
if(!(graphisGridGraph||graphisRecastGraph))thrownewSystem.Exception("The ProceduralGraphMover was configured to use graph index "+graphIndex+" but that graph either does not exist or is not a GridGraph, LayerGridGraph or RecastGraph");
if(graphisRecastGraphrg&&!rg.useTiles)Debug.LogWarning("The ProceduralGraphMover component only works with tiled recast graphs. Enable tiling in the recast graph inspector.",this);
}
UpdateGraph();
}
voidOnDisable(){
// Just in case this script is performing an update while being disabled