A* Pathfinding Project
3.6
The A* Pathfinding Project for Unity 3D
|
Many graphs supports updating during runtime without a complete rescan. Best implemented is the GridGraph and PointGraph, but navmesh based ones also has support for it.
Graph Updates can either be done using the GraphUpdateScene component which does all the heavy work for you or using scripting which is done by calling a central function in the AstarPath class with either a Bounds object or a Pathfinding::GraphUpdateObject (which is what the GraphUpdateScene component actually does in the background).
The function will then put the task in a queue to be carried out before the next path calculation. It has to be put in a queue because if it carried out directly, it might interfere with pathfinding, especially if multithreading is on, and cause all kinds of errors. This means that you might not see an update of the graph directly, but it will always be updated before the next pathfinding calculation starts (almost always, see AstarPath.limitGraphUpdates ).
Recast graphs can be pseudo-updated using navmesh cutting. Navmesh cutting can cut out holes for obstacles in the navmesh, but cannot add more navmesh surface. See NavmeshCut.
The GraphUpdateScene component is really easy to use. Create a new empty GameObject and add the component to it, it can be found in Components–>Pathfinding–>GraphUpdateScene.
When you have added the component, you should see something like the image below.
The above code will make it apply it's changes to the graph (assuming a GraphUpdateScene component is attached to the same GameObject).
Next there is "Modify Walkability" and "Set Walkability" (which appears when "Modify Walkability" is toggled). If Modify Walkability is set, then all nodes inside the area will either be set to walkable or unwalkable depending on the value of the "Set Walkability" variable.
Penalty can also be applied to the nodes. A higher penalty (aka weight) makes the nodes harder to traverse so it will try to avoid those areas.
The tagging variables can be read more about on this page: Working with tags.
When updating is carried out, all graphs will be looped over and those which can be updated (all built in ones) will have their UpdateArea function called (i.e be updated).
Each node is updated by the graphs calling Pathfinding::GraphUpdateObject::Apply sending each affected node to it, the Apply function will then change penalty, walkability or other parameters specified. Graphs can also use custom updating logic, such as the GridGraph (see Updating GridGraphs). You do not have to understand all different function calls to be able to use it, those are mostly for people who want to mess around with the source code.
A common task is to add a penalty (weight) to some nodes to make it be avoided by the algorithm, in other words make the area slower/harder to traverse. This can be done relatively easy using GraphUpdateObjects.
The myBounds variable referred to is a UnityEngine.Bounds object. It defines an axis aligned box in which to update the graphs in.
If you don't need to update walkability when using a grid graph or connections when using a point graph, you can set updatePhysics (see Updating GridGraphs) to false to avoid unnecessary calculations
The GraphUpdateObject::updatePhysics variable matters a lot when updating grid graphs. If it is set to true, all nodes affected will have their height recalculated and then checked if they are still walkable. You usually want to leave this to true when updating a grid graph.
A common misstake is to create a new obstacle in the scene, and do something like this:
And expect the area under the obstacle to become unwalkable. The misstake is often that one does not check that the obstacle is in a layer which would make the nodes unwalkable in the first place. The GridGraph's settings for collision checking has a mask field, one must make sure the obstacle is in a layer contained in that mask.
When updating a GridGraph, the GraphUpdateObject's Apply function will be called for each node inside the bounds, it will check the GraphUpdateObject::updatePhysics variable, if it is true (which is the default value), the area will be expanded by the diameter of the Collision Testing and every node inside the area will be checked for collisions. If it is false, however, only the Apply function will be called for the nodes inside the area (not expanded) and nothing else will be done.
Navmesh based graphs (NavMeshGraph and RecastGraph) only have support for updating penalty, walkability and similar on already existing nodes. New nodes cannot be created using GraphUpdateObjects. The GraphUpdateObject will affect all nodes/triangles which intersect or are contained by the GUO's bounds.
Point graphs will call Apply on every node inside the bounds and also, if GraphUpdateObject::updatePhysics is set to true (default true), it will recalculate any connections which passes through the bounds object.
The GraphUpdateObject contains some basic variables on how to update each node. See documentation for the Pathfinding::GraphUpdateObject for more info.
Classes can inherit from the GraphUpdateObject to override some functionality.
Here's an example of a GraphUpdateObject which moves nodes by some offset while still keeping the base functionality.
You could then use that GUO like this: