Public
Generates a grid of nodes.
The GridGraph does exactly what the name implies, generates nodes in a grid pattern.
Grid graphs are excellent for when you already have a grid-based world. But they also work well for free-form worlds.
Features
Throw any scene at it, and with minimal configurations you can get a good graph from it.
Predictable pattern.
Grid graphs work well with penalties and tags.
You can update parts of the graph during runtime.
Graph updates are fast.
Scanning the graph is comparatively fast.
Supports linecasting.
Supports the funnel modifier.
Supports both 2D and 3D physics.
Supports isometric and hexagonal node layouts.
Can apply penalty and walkability values from a supplied image.
Perfect for terrains since it can make nodes walkable or unwalkable depending on the slope.
Only supports a single layer, but you can use a LayerGridGraph if you need more layers.
Inspector
A grid graph can be set up as a normal grid, isometric grid or hexagonal grid. Each of these modes use a slightly different inspector layout. When changing the shape in the inspector, it will automatically set other relevant fields to appropriate values. For example, when setting the shape to hexagonal it will automatically set the neighbours field to Six.
This field is only used in the editor, it has no effect on the rest of the game whatsoever.
If you want to change the grid shape like in the inspector you can use the SetGridShape method.
NoteThis is just a convenience property, this property will actually read/modify the rotation of the graph. A rotation aligned with the 2D plane is what determines if the graph is 2D or not.
SeeYou can also set if the graph should use 2D physics using `this.collision.use2D` ( GraphCollision.use2D).
See
This setting corresponds to the member
is2D
This is very handy if your game uses a tilemap for rendering and you want to make sure the graph is laid out exactly the same. Matching grid parameters manually can be quite tricky in some cases.
The inspector will automatically show a button to align to a tilemap if one is detected in the scene. If no tilemap is detected, the button be hidden.
Grid graphs are typically anywhere from 10-500 nodes wide. But it can go up to 1024 nodes wide by default. Consider using a recast graph instead, if you find yourself needing a very high resolution grid.
This value will be clamped to at most 1024 unless ASTAR_LARGER_GRIDS has been enabled in the A* Inspector -> Optimizations tab.
See
This setting corresponds to the member
width
Grid graphs are typically anywhere from 10-500 nodes wide. But it can go up to 1024 nodes wide by default. Consider using a recast graph instead, if you find yourself needing a very high resolution grid.
This value will be clamped to at most 1024 unless ASTAR_LARGER_GRIDS has been enabled in the A* Inspector -> Optimizations tab.
See
This setting corresponds to the member
depth
For a grid layout, this is the length of the sides of the grid squares.
For a hexagonal layout, this value does not correspond to any specific dimension of the hexagon. Instead you can convert it to a dimension on a hexagon using ConvertNodeSizeToHexagonSize.
See
This setting corresponds to the member
nodeSize
This should be used if you want different scales on the X and Y axis of the grid
This option is only visible in the inspector if the graph shape is set to isometric or advanced.
If you are making a 2D isometric game, you may want to use this parameter to adjust the layout of the graph to match your game. This will essentially scale the graph along one of its diagonals to produce something like this:
A perspective view of an isometric graph.
A top down view of an isometric graph. Note that the graph is entirely 2D, there is no perspective in this image.
For commonly used values see StandardIsometricAngle and StandardDimetricAngle.
Usually the angle that you want to use is either 30 degrees (alternatively 90-30 = 60 degrees) or atan(1/sqrt(2)) which is approximately 35.264 degrees (alternatively 90 - 35.264 = 54.736 degrees). You might also want to rotate the graph plus or minus 45 degrees around the Y axis to get the oritientation required for your game.
You can read more about it on the wikipedia page linked below.
This option is only visible in the inspector if the graph shape is set to isometric or advanced.
The graph can be positioned anywhere in the world.
See
This setting corresponds to the member
center
The nodes are laid out along the X and Z axes of the rotation.
For a 2D game, the rotation will typically be set to (-90, 270, 90). If the graph is aligned with the XY plane, the inspector will automatically switch to 2D mode.
See
This setting corresponds to the member
rotation
Either four, six, eight connections per node.
Six connections is primarily for hexagonal graphs.
See
This setting corresponds to the member
neighbours
If this is true, and neighbours is set to Eight, obstacle corners are allowed to be cut by a connection.
See
This setting corresponds to the member
cutCorners
Set to 0 to ignore the value.
This affects for example how the graph is generated around ledges and stairs.
VersionWas previously called maxClimb
When this is enabled the normals of the terrain will be used to make more accurate estimates of how large the steps are between adjacent nodes.
When this is disabled then calculated step between two nodes is their y coordinate difference. This may be inaccurate, especially at the start of steep slopes.
In the image below you can see an example of what happens near a ramp. In the topmost image the ramp is not connected with the rest of the graph which is obviously not what we want. In the middle image an attempt has been made to raise the max step height while keeping maxStepUsesSlope disabled. However this causes too many connections to be added. The agent should not be able to go up the ramp from the side. Finally in the bottommost image the maxStepHeight has been restored to the original value but maxStepUsesSlope has been enabled. This configuration handles the ramp in a much smarter way. Note that all the values in the image are just example values, they may be different for your scene.
See
This setting corresponds to the member
maxSlope
The graph can be eroded to add extra margin to obstacles. It is very convenient if your graph contains ledges, and where the walkable nodes without erosion are too close to the edge.
Below is an image showing a graph with 0, 1 and 2 erosion iterations:
NoteA high number of erosion iterations can slow down graph updates during runtime. This is because the region that is updated needs to be expanded by the erosion iterations times two to account for possible changes in the border nodes.
If enabled, the 2D Physics API will be used, and if disabled, the 3D Physics API will be used.
This changes the collider types (see type) from 3D versions to their corresponding 2D versions. For example the sphere shape becomes a circle.
The heightCheck setting will be ignored when 2D physics is used.
Collision testing
When checking for collisions the system will check if any colliders overlap a specific shape at the node's position. The shape is determined by the type field.
A diameter of 1 means that the shape has a diameter equal to the node's width, or in other words it is equal to nodeSize .
If type is set to Ray, this does not affect anything.
If type is set to Sphere, this does not affect anything.
WarningIn contrast to Unity's capsule collider and character controller this height does not include the end spheres of the capsule, but only the cylinder part. This is mostly for historical reasons.
For example, if the ground was found at y=0, collisionOffset = 2 type = Capsule and height = 3 then the physics system will be queried to see if there are any colliders in a capsule for which the bottom sphere that is made up of is centered at y=2 and the top sphere has its center at y=2+3=5.
If type = Sphere then the sphere's center would be at y=2 in this case.
On the left you can see a top-down view of the graph with a grid of nodes. On the right you can see a side view of the graph. The white line at the bottom is the base of the graph, with node positions indicated using small dots. When using 2D physics, only the top-down view is visible.
The green shape indicates the shape that will be used for collision checking.
Height testing
As the image below visualizes, different ray lengths can make the ray hit different things. The distance is measured up from the graph plane.
If height raycast is turned off, this doesn't affect anything.
Rules
Take a look at Grid Graph Rules for a list of available rules.
Other settings
Each node will be drawn as a square (unless e.g hexagon graph mode has been enabled).
Updating the graph during runtime
Any graph which implements the IUpdatableGraph interface can be updated during runtime. For grid graphs this is a great feature since you can update only a small part of the grid without causing any lag like a complete rescan would.
If you for example just have instantiated an obstacle in the scene and you want to update the grid where that obstacle was instantiated, you can do this:
AstarPath.active.UpdateGraphs (obstacle.collider.bounds);
Where obstacle is the GameObject you just instantiated.
As you can see, the UpdateGraphs function takes a Bounds parameter and it will send an update call to all updateable graphs.
A grid graph will assume anything could have changed inside that bounding box, and recalculate all nodes that could possibly be affected. Thus it may end up updating a few more nodes than just those covered by the bounding box.
Hexagonal graphs
The graph can be configured to work like a hexagon graph with some simple settings. The grid graph has a Shape dropdown. If you set it to 'Hexagonal' the graph will behave as a hexagon graph. Often you may want to rotate the graph +45 or -45 degrees.
NoteSnapping to the closest node is not exactly as you would expect in a real hexagon graph, but it is close enough that you will likely not notice.
A grid graph can be added and configured completely at runtime via code.
// This holds all graph data
AstarData data = AstarPath.active.data;
// This creates a Grid Graph
GridGraph gg = data.AddGraph(typeof(GridGraph)) as GridGraph;
// Setup a grid graph with some values
int width = 50;
int depth = 50;
float nodeSize = 1;
gg.center = new Vector3(10, 0, 0);
// Updates internal size from the above values
gg.SetDimensions(width, depth, nodeSize);
// Scans all graphs
AstarPath.active.Scan();
Tree colliders
It seems that Unity will only generate tree colliders at runtime when the game is started. For this reason, the grid graph will not pick up tree colliders when outside of play mode but it will pick them up once the game starts. If it still does not pick them up make sure that the trees actually have colliders attached to them and that the tree prefabs are in the correct layer (the layer should be included in the 'Collision Testing' mask).
Inner Types
Public Methods
void
AlignToTilemap
(
UnityEngine.GridLayout | grid | |
)
Aligns this grid to a given tilemap or grid layout.
This is very handy if your game uses a tilemap for rendering and you want to make sure the graph is laid out exactly the same. Matching grid parameters manually can be quite tricky in some cases.
The inspector will automatically show a button to align to a tilemap if one is detected in the scene. If no tilemap is detected, the button be hidden.
void
CalculateConnectionsForCellAndNeighbours
(
)
Calculates the grid connections for a cell as well as its neighbours.
This is a useful utility function if you want to modify the walkability of a single node in the graph.
AstarPath.active.AddWorkItem(ctx => {
var grid = AstarPath.active.data.gridGraph;
int x = 5;
int z = 7;
// Mark a single node as unwalkable
grid.GetNode(x, z).Walkable = false;
// Recalculate the connections for that node as well as its neighbours
grid.CalculateConnectionsForCellAndNeighbours(x, z);
});
WarningIf you are recalculating connections for a lot of nodes at the same time, use RecalculateConnectionsInRegion instead, since that will be much faster.
int
CountNodes
()
Number of nodes in the graph.
Note that this is, unless the graph type has overriden it, an O(n) operation.
This is an O(1) operation for grid graphs and point graphs. For layered grid graphs it is an O(n) operation.
Bounds
GetBoundsFromRect
(
IntRect | rect | Which nodes to consider. Will be clamped to the grid's bounds. If the rectangle is outside the graph, an empty bounds will be returned. |
)
Bounding box in world space which encapsulates all nodes in the given rectangle.
The bounding box will cover all nodes' surfaces completely. Not just their centers.
NoteThe bounding box may not be particularly tight if the graph is not axis-aligned.
uint
GetConnectionCost
(
)
Default cost of moving one node in a particular direction.
NoteYou can only call this after the graph has been scanned. Otherwise it will return zero.
Z
|
|
6 2 5
\ | /
-- 3 - X - 1 ----- X
/ | \
7 0 4
|
|
NNInfo
GetNearest
(
Vector3 | position | The position to try to find the closest node to. |
NNConstraint | constraint | Used to limit which nodes are considered acceptable. You may, for example, only want to consider walkable nodes. If null, all nodes will be considered acceptable. |
float | maxDistanceSqr | The maximum squared distance from the position to the node. If the node is further away than this, the function will return an empty NNInfo. You may pass infinity if you do not want to limit the distance. |
)
Nearest node to a position using the specified NNConstraint.
The returned NNInfo will contain both the closest node, and the closest point on the surface of that node. The distance is measured to the closest point on the surface of the node.
SeeYou can use AstarPath.GetNearest instead, if you want to check all Graph Types.
)
Node in the specified cell.
Returns null if the coordinate is outside the grid.
var gg = AstarPath.active.data.gridGraph;
int x = 5;
int z = 8;
GridNodeBase node = gg.GetNode(x, z);
If you know the coordinate is inside the grid and you are looking to maximize performance then you can look up the node in the internal array directly which is slightly faster.
void
GetNodes
(
)
Calls a delegate with all nodes in the graph.
This is the primary way of iterating through all nodes in a graph.
Do not change the graph structure inside the delegate.
var gg = AstarPath.active.data.gridGraph;
gg.GetNodes(node => {
// Here is a node
Debug.Log("I found a node at position " + (Vector3)node.position);
});
If you want to store all nodes in a list you can do this
var gg = AstarPath.active.data.gridGraph;
List<GraphNode> nodes = new List<GraphNode>();
gg.GetNodes((System.Action<GraphNode>)nodes.Add);
List<GraphNode>
GetNodesInRegion
(
)
All nodes inside the bounding box.
NoteBe nice to the garbage collector and pool the list when you are done with it (optional)
List<GraphNode>
GetNodesInRegion
(
)
All nodes inside the shape.
NoteBe nice to the garbage collector and pool the list when you are done with it (optional)
List<GraphNode>
GetNodesInRegion
(
IntRect | rect | Region in which to return nodes. It will be clamped to the grid. |
)
Get all nodes in a rectangle.
int
GetNodesInRegion
(
IntRect | rect | Region in which to return nodes. It will be clamped to the grid. |
GridNodeBase[] | buffer | Buffer in which the nodes will be stored. Should be at least as large as the number of nodes that can exist in that region. |
)
Get all nodes in a rectangle.
ReturnThe number of nodes written to the buffer.
NoteThis method is much faster than GetNodesInRegion(IntRect) which returns a list because this method can make use of the highly optimized System.Array.Copy method.
IntRect
GetRectFromBounds
(
)
A rect that contains all nodes that the bounds could touch.
This correctly handles rotated graphs and other transformations. The returned rect is guaranteed to not extend outside the graph bounds.
NoteThe rect may contain nodes that are not contained in the bounding box since the bounding box is aligned to the world, and the rect is aligned to the grid (which may be rotated).
Int3
GraphPointToWorld
(
)
Transform a point in graph space to world space.
This will give you the node position for the node at the given x and z coordinate if it is at the specified height above the base of the graph.
bool
IsInsideBounds
(
)
True if the point is inside the bounding box of this graph.
For a graph that uses 2D physics, or if height testing is disabled, then the graph is treated as infinitely tall. Otherwise, the height of the graph is determined by GraphCollision.fromHeight.
NoteFor an unscanned graph, this will always return false.
bool
Linecast
(
)
Returns if there is an obstacle between from and to on the graph.
This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
var gg = AstarPath.active.data.gridGraph;
bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position);
Edge cases are handled as follows:
Shared edges and corners between walkable and unwalkable nodes are treated as walkable (so for example if the linecast just touches a corner of an unwalkable node, this is allowed).
If the linecast starts outside the graph, a hit is returned at from.
If the linecast starts inside the graph, but the end is outside of it, a hit is returned at the point where it exits the graph (unless there are any other hits before that).
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
bool
Linecast
(
Vector3 | from | Point to linecast from |
Vector3 | to | Point to linecast to |
outGraphHitInfo | hit | Contains info on what was hit, see GraphHitInfo. |
List<GraphNode> | trace=null | If a list is passed, then it will be filled with all nodes the linecast traverses |
System.Func<GraphNode, bool> | filter=null | If not null then the delegate will be called for each node and if it returns false the node will be treated as unwalkable and a hit will be returned. Note that unwalkable nodes are always treated as unwalkable regardless of what this filter returns. |
)
Returns if there is an obstacle between from and to on the graph.
This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
Edge cases are handled as follows:
Shared edges and corners between walkable and unwalkable nodes are treated as walkable (so for example if the linecast just touches a corner of an unwalkable node, this is allowed).
If the linecast starts outside the graph, a hit is returned at from.
If the linecast starts inside the graph, but the end is outside of it, a hit is returned at the point where it exits the graph (unless there are any other hits before that).
var gg = AstarPath.active.data.gridGraph;
bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position);
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
bool
Linecast
(
GridNodeBase | fromNode | Node to start from. |
GridNodeBase | toNode | Node to try to reach using a straight line. |
System.Func<GraphNode, bool> | filter=null | If not null then the delegate will be called for each node and if it returns false the node will be treated as unwalkable and a hit will be returned. Note that unwalkable nodes are always treated as unwalkable regardless of what this filter returns. |
)
Returns if there is an obstacle between the two nodes on the graph.
This method is very similar to the other Linecast methods however it is a bit faster due to not having to look up which node is closest to a particular input point.
var gg = AstarPath.active.data.gridGraph;
var node1 = gg.GetNode(2, 3);
var node2 = gg.GetNode(5, 7);
bool anyObstaclesInTheWay = gg.Linecast(node1, node2);
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
bool
Linecast
(
Vector3 | from | Point to linecast from |
Vector3 | to | Point to linecast to |
outGridHitInfo | hit | Contains info on what was hit, see GridHitInfo |
List<GraphNode> | trace=null | If a list is passed, then it will be filled with all nodes the linecast traverses |
System.Func<GraphNode, bool> | filter=null | If not null then the delegate will be called for each node and if it returns false the node will be treated as unwalkable and a hit will be returned. Note that unwalkable nodes are always treated as unwalkable regardless of what this filter returns. |
)
Returns if there is an obstacle between from and to on the graph.
This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
NoteThis overload outputs a hit of type GridHitInfo instead of GraphHitInfo. It's a bit faster to calculate this output and it can be useful for some grid-specific algorithms.
Edge cases are handled as follows:
Shared edges and corners between walkable and unwalkable nodes are treated as walkable (so for example if the linecast just touches a corner of an unwalkable node, this is allowed).
If the linecast starts outside the graph, a hit is returned at from.
If the linecast starts inside the graph, but the end is outside of it, a hit is returned at the point where it exits the graph (unless there are any other hits before that).
var gg = AstarPath.active.data.gridGraph;
bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position);
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
bool
Linecast
(
GridNodeBase | fromNode | Node to start from. |
Vector2 | normalizedFromPoint | Where in the start node to start. This is a normalized value so each component must be in the range 0 to 1 (inclusive). |
GridNodeBase | toNode | Node to try to reach using a straight line. |
Vector2 | normalizedToPoint | Where in the end node to end. This is a normalized value so each component must be in the range 0 to 1 (inclusive). |
outGridHitInfo | hit | Contains info on what was hit, see GridHitInfo |
List<GraphNode> | trace=null | If a list is passed, then it will be filled with all nodes the linecast traverses |
System.Func<GraphNode, bool> | filter=null | If not null then the delegate will be called for each node and if it returns false the node will be treated as unwalkable and a hit will be returned. Note that unwalkable nodes are always treated as unwalkable regardless of what this filter returns. |
bool | continuePastEnd=false | If true, the linecast will continue past the end point in the same direction until it hits something. |
)
Returns if there is an obstacle between the two nodes on the graph.
This method is very similar to the other Linecast methods but it gives some extra control, in particular when the start/end points are at node corners instead of inside nodes.
Shared edges and corners between walkable and unwalkable nodes are treated as walkable. So for example if the linecast just touches a corner of an unwalkable node, this is allowed.
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
float
NearestNodeDistanceSqrLowerBound
(
Vector3 | position | The position to check from |
NNConstraint | constraint | A constraint on which nodes are valid. This may or may not be used by the function. You may pass null if you consider all nodes valid. |
)
Lower bound on the squared distance from the given point to the closest node in this graph.
This is used to speed up searching for the closest node when there is more than one graph in the scene, by checking the graphs in order of increasing estimated distance to the point.
Implementors may return 0 at all times if it is hard to come up with a good lower bound. It is more important that this function is fast than that it is accurate.
void
OnDrawGizmos
(
DrawingData | gizmos | |
bool | drawNodes | |
RedrawScope | redrawScope | |
)
Draw gizmos for the graph.
void
RecalculateAllConnections
()
Recalculates node connections for all nodes in grid graph.
This is used if you have manually changed the walkability, or other parameters, of some grid nodes, and you need their connections to be recalculated. If you are changing the connections themselves, you should use the GraphNode.Connect and GraphNode.Disconnect functions instead.
Typically you do not change walkability manually. Instead you can use for example a GraphUpdateObject.
NoteThis will not take into account any grid graph rules that modify connections. So if you have any of those added to the grid graph, you probably want to do a regular graph update instead.
void
RecalculateConnectionsInRegion
(
)
Recalculates node connections for all nodes in a given region of the grid.
This is used if you have manually changed the walkability, or other parameters, of some grid nodes, and you need their connections to be recalculated. If you are changing the connections themselves, you should use the GraphNode.AddConnection and GraphNode.RemoveConnection functions instead.
Typically you do not change walkability manually. Instead you can use for example a GraphUpdateObject.
WarningThis method has some constant overhead, so if you are making several changes to the graph, it is best to batch these updates and only make a single call to this method.
NoteThis will not take into account any grid graph rules that modify connections. So if you have any of those added to the grid graph, you probably want to do a regular graph update instead.
void
RelocateNodes
(
)
Moves the nodes in this graph.
Multiplies all node positions by deltaMatrix.
For example if you want to move all your nodes in e.g a point graph 10 units along the X axis from the initial position var graph = AstarPath.data.pointGraph;
var m = Matrix4x4.TRS (new Vector3(10,0,0), Quaternion.identity, Vector3.one);
graph.RelocateNodes (m);
NoteFor grid graphs, navmesh graphs and recast graphs it is recommended to use their custom overloads of the RelocateNodes method which take parameters for e.g center and nodeSize (and additional parameters) instead since they are both easier to use and are less likely to mess up pathfinding.
WarningThis method is lossy for PointGraphs, so calling it many times may cause node positions to lose precision. For example if you set the scale to 0 in one call then all nodes will be scaled/moved to the same point and you will not be able to recover their original positions. The same thing happens for other - less extreme - values as well, but to a lesser degree.
void
RelocateNodes
(
Vector3 | center | |
Quaternion | rotation | |
float | nodeSize | |
float | aspectRatio=1 | |
float | isometricAngle=0 | |
)
Relocate the grid graph using new settings.
This will move all nodes in the graph to new positions which matches the new settings.
// Move the graph to the origin, with no rotation, and with a node size of 1.0
var gg = AstarPath.active.data.gridGraph;
gg.RelocateNodes(center: Vector3.zero, rotation: Quaternion.identity, nodeSize: 1.0f);
void
SetGridShape
(
)
Changes the grid shape.
This is equivalent to changing the 'shape' dropdown in the grid graph inspector.
Calling this method will set isometricAngle, aspectRatio, uniformEdgeCosts and neighbours to appropriate values for that shape.
NoteSetting the shape to InspectorGridMode.Advanced does not do anything except set the inspectorGridMode field.
void
SetWalkability
(
)
Set walkability for multiple nodes at once.
If you are calculating your graph's walkability in some custom way, you can use this method to copy that data to the graph. In most cases you'll not use this method, but instead build your world with colliders and such, and then scan the graph.
NoteAny other graph updates may overwrite this data.
AstarPath.active.AddWorkItem(() => {
var grid = AstarPath.active.data.gridGraph;
// Mark all nodes in a 10x10 square, in the top-left corner of the graph, as unwalkable.
grid.SetWalkability(new bool[10*10], new IntRect(0, 0, 9, 9));
});
SeeGrid Graph Rules for an alternative way of modifying the graph's walkability. It is more flexible and robust, but requires a bit more code.
)
Captures a snapshot of a part of the graph, to allow restoring it later.
If this graph type does not support taking snapshots, or if the bounding box does not intersect with the graph, this method returns null.
int | dx | Number of nodes along the graph's X axis to move by. |
int | dz | Number of nodes along the graph's Z axis to move by. |
)
Moves the grid by a number of nodes.
This is used by the ProceduralGraphMover component to efficiently move the graph.
All nodes that can stay in the same position will stay. The ones that would have fallen off the edge of the graph will wrap around to the other side and then be recalculated.
Public Static Methods
float
ConvertHexagonSizeToNodeSize
(
)
Converts a hexagon dimension to a node size.
A hexagon can be defined using either its diameter, or width, none of which are the same as the nodeSize used internally to define the size of a single node.
float
ConvertNodeSizeToHexagonSize
(
)
Converts an internal node size to a hexagon dimension.
A hexagon can be defined using either its diameter, or width, none of which are the same as the nodeSize used internally to define the size of a single node.
int[]
GetNeighbourDirections
(
)
Neighbour direction indices to use depending on how many neighbours each node should have.
The following illustration shows the direction indices for all 8 neighbours, Z
|
|
6 2 5
\ | /
-- 3 - X - 1 ----- X
/ | \
7 0 4
|
|
For other neighbour counts, a subset of these will be returned.
These can then be used to index into the neighbourOffsets, neighbourCosts, neighbourXOffsets, and neighbourZOffsets arrays.
Public Variables
int
LayerCount
Number of layers in the graph.
For grid graphs this is always 1, for layered grid graphs it can be higher. The nodes array has the size width*depth*layerCount.
float
aspectRatio = 1F
Scaling of the graph along the X axis.
This should be used if you want different scales on the X and Y axis of the grid
This option is only visible in the inspector if the graph shape is set to isometric or advanced.
World bounding box for the graph.
This always contains the whole graph.
NoteSince this is an axis-aligned bounding box, it may not be particularly tight if the graph is significantly rotated.
Center point of the grid in world space.
The graph can be positioned anywhere in the world.
Settings on how to check for walkability and height.
bool
cutCorners = true
If disabled, will not cut corners on obstacles.
If this is true, and neighbours is set to Eight, obstacle corners are allowed to be cut by a connection.
int
depth
Depth (height) of the grid in nodes.
Grid graphs are typically anywhere from 10-500 nodes wide. But it can go up to 1024 nodes wide by default. Consider using a recast graph instead, if you find yourself needing a very high resolution grid.
This value will be clamped to at most 1024 unless ASTAR_LARGER_GRIDS has been enabled in the A* Inspector -> Optimizations tab.
int
erodeIterations
Number of times to erode the graph.
The graph can be eroded to add extra margin to obstacles. It is very convenient if your graph contains ledges, and where the walkable nodes without erosion are too close to the edge.
Below is an image showing a graph with 0, 1 and 2 erosion iterations:
NoteA high number of erosion iterations can slow down graph updates during runtime. This is because the region that is updated needs to be expanded by the erosion iterations times two to account for possible changes in the border nodes.
int
erosionFirstTag = 1
Tag to start from when using tags for erosion.
InspectorGridMode
inspectorGridMode = InspectorGridMode.Grid
Determines the layout of the grid graph inspector in the Unity Editor.
A grid graph can be set up as a normal grid, isometric grid or hexagonal grid. Each of these modes use a slightly different inspector layout. When changing the shape in the inspector, it will automatically set other relevant fields to appropriate values. For example, when setting the shape to hexagonal it will automatically set the neighbours field to Six.
This field is only used in the editor, it has no effect on the rest of the game whatsoever.
If you want to change the grid shape like in the inspector you can use the SetGridShape method.
InspectorGridHexagonNodeSize
inspectorHexagonSizeMode = InspectorGridHexagonNodeSize.Width
Determines how the size of each hexagon is set in the inspector.
For hexagons the normal nodeSize field doesn't really correspond to anything specific on the hexagon's geometry, so this enum is used to give the user the opportunity to adjust more concrete dimensions of the hexagons without having to pull out a calculator to calculate all the square roots and complicated conversion factors.
This field is only used in the graph inspector, the nodeSize field will always use the same internal units. If you want to set the node size through code then you can use ConvertHexagonSizeToNodeSize.
bool?
is2D
Get or set if the graph should be in 2D mode.
NoteThis is just a convenience property, this property will actually read/modify the rotation of the graph. A rotation aligned with the 2D plane is what determines if the graph is 2D or not.
SeeYou can also set if the graph should use 2D physics using `this.collision.use2D` ( GraphCollision.use2D).
float
isometricAngle
Angle in degrees to use for the isometric projection.
If you are making a 2D isometric game, you may want to use this parameter to adjust the layout of the graph to match your game. This will essentially scale the graph along one of its diagonals to produce something like this:
A perspective view of an isometric graph.
A top down view of an isometric graph. Note that the graph is entirely 2D, there is no perspective in this image.
For commonly used values see StandardIsometricAngle and StandardDimetricAngle.
Usually the angle that you want to use is either 30 degrees (alternatively 90-30 = 60 degrees) or atan(1/sqrt(2)) which is approximately 35.264 degrees (alternatively 90 - 35.264 = 54.736 degrees). You might also want to rotate the graph plus or minus 45 degrees around the Y axis to get the oritientation required for your game.
You can read more about it on the wikipedia page linked below.
This option is only visible in the inspector if the graph shape is set to isometric or advanced.
float
maxSlope = 90
The max slope in degrees for a node to be walkable.
float
maxStepHeight = 0.4F
The max y coordinate difference between two nodes to enable a connection.
Set to 0 to ignore the value.
This affects for example how the graph is generated around ledges and stairs.
VersionWas previously called maxClimb
bool
maxStepUsesSlope = true
Take the slope into account for maxStepHeight.
When this is enabled the normals of the terrain will be used to make more accurate estimates of how large the steps are between adjacent nodes.
When this is disabled then calculated step between two nodes is their y coordinate difference. This may be inaccurate, especially at the start of steep slopes.
In the image below you can see an example of what happens near a ramp. In the topmost image the ramp is not connected with the rest of the graph which is obviously not what we want. In the middle image an attempt has been made to raise the max step height while keeping maxStepUsesSlope disabled. However this causes too many connections to be added. The agent should not be able to go up the ramp from the side. Finally in the bottommost image the maxStepHeight has been restored to the original value but maxStepUsesSlope has been enabled. This configuration handles the ramp in a much smarter way. Note that all the values in the image are just example values, they may be different for your scene.
uint[]
neighbourCosts = new uint[8]
Costs to neighbour nodes.
See neighbourOffsets.
int[]
neighbourOffsets = new int[8]
Index offset to get neighbour nodes.
Added to a node's index to get a neighbour node index.
Z
|
|
6 2 5
\ | /
-- 3 - X - 1 ----- X
/ | \
7 0 4
|
|
NumNeighbours
neighbours = NumNeighbours.Eight
Number of neighbours for each node.
Either four, six, eight connections per node.
Six connections is primarily for hexagonal graphs.
float
nodeSize = 1
Size of one node in world units.
For a grid layout, this is the length of the sides of the grid squares.
For a hexagonal layout, this value does not correspond to any specific dimension of the hexagon. Instead you can convert it to a dimension on a hexagon using ConvertNodeSizeToHexagonSize.
All nodes in this graph.
Nodes are laid out row by row.
The first node has grid coordinates X=0, Z=0, the second one X=1, Z=0
the last one has grid coordinates X=width-1, Z=depth-1.
var gg = AstarPath.active.data.gridGraph;
int x = 5;
int z = 8;
GridNodeBase node = gg.nodes[z*gg.width + x];
Rotation of the grid in degrees.
The nodes are laid out along the X and Z axes of the rotation.
For a 2D game, the rotation will typically be set to (-90, 270, 90). If the graph is aligned with the XY plane, the inspector will automatically switch to 2D mode.
bool
showMeshOutline = true
Show an outline of the grid nodes in the Unity Editor.
bool
showMeshSurface = true
Show the surface of the graph.
Each node will be drawn as a square (unless e.g hexagon graph mode has been enabled).
bool
showNodeConnections
Show the connections between the grid nodes in the Unity Editor.
Size of the grid.
Will always be positive and larger than nodeSize.
Vector2
unclampedSize = new Vector2(10, 10)
Size of the grid.
Can be negative or smaller than nodeSize
int
width
Width of the grid in nodes.
Grid graphs are typically anywhere from 10-500 nodes wide. But it can go up to 1024 nodes wide by default. Consider using a recast graph instead, if you find yourself needing a very high resolution grid.
This value will be clamped to at most 1024 unless ASTAR_LARGER_GRIDS has been enabled in the A* Inspector -> Optimizations tab.
Public Static Variables
const int
FixedPrecisionScale = 1024
Scaling used for the coordinates in the Linecast methods that take normalized points using integer coordinates.
To convert from world space, each coordinate is multiplied by this factor and then rounded to the nearest integer.
Typically you do not need to use this constant yourself, instead use the Linecast overloads that do not take integer coordinates.
float
StandardDimetricAngle = Mathf.Acos(1/2f)*Mathf.Rad2Deg
Commonly used value for isometricAngle.
float
StandardIsometricAngle = 90-Mathf.Atan(1/Mathf.Sqrt(2))*Mathf.Rad2Deg
Commonly used value for isometricAngle.
int[]
neighbourXOffsets = { 0, 1, 0, -1, 1, 1, -1, -1 }
Offsets in the X direction for neighbour nodes.
Only 1, 0 or -1
int[]
neighbourZOffsets = { -1, 0, 1, 0, -1, 1, 1, -1 }
Offsets in the Z direction for neighbour nodes.
Only 1, 0 or -1
Public Enums
RecalculationMode
RecalculateFromScratch |
Recalculates the nodes from scratch.
Used when the graph is first scanned. You should have destroyed all existing nodes before updating the graph with this mode. |
RecalculateMinimal |
Recalculate the minimal number of nodes necessary to guarantee changes inside the graph update's bounding box are taken into account.
Some data may be read from the existing nodes |
NoRecalculation |
Nodes are not recalculated.
Used for graph updates which only set node properties |
Inherited Public Members
NNInfo
GetNearest
(
Vector3 | position | The position to try to find the closest node to. |
NNConstraint | constraint=null | Used to limit which nodes are considered acceptable. You may, for example, only want to consider walkable nodes. If null, all nodes will be considered acceptable. |
)
Returns the nearest node to a position using the specified NNConstraint.
The returned NNInfo will contain both the closest node, and the closest point on the surface of that node. The distance is measured to the closest point on the surface of the node.
VersionBefore 4.3.63, this method would not use the NNConstraint in all cases.
void
GetNodes
(
)
Calls a delegate with all nodes in the graph until the delegate returns false.
bool
IsPointOnNavmesh
(
Vector3 | position | The point to check |
)
True if the point is on a walkable part of the navmesh, as seen from above.
A point is considered on the navmesh if it is above or below a walkable navmesh surface, at any distance, and if it is not above/below a closer unwalkable node.
This uses the graph's natural up direction to determine which way is up. Therefore, it will also work on rotated graphs, as well as graphs in 2D mode.
This method works for all graph types. However, for PointGraphs, this will never return true unless you pass in the exact coordinate of a node, since point nodes do not have a surface.
NoteFor spherical navmeshes (or other weird shapes), this method will not work as expected, as there's no well defined "up" direction.
void
Scan
()
Scan the graph.
Consider using AstarPath.Scan() instead since this function only scans this graph, and if you are using multiple graphs with connections between them, then it is better to scan all graphs at once.
Reference to the AstarPath object in the scene.
World bounding box for the graph.
This always contains the whole graph.
NoteSince this an axis aligned bounding box, it may not be particularly tight if the graph is rotated.
It is ok for a graph type to return an infinitely large bounding box, but this may make some operations less efficient. The point graph will always return an infinitely large bounding box.
bool
drawGizmos = true
Enable to draw gizmos in the Unity scene view.
In the inspector this value corresponds to the state of the 'eye' icon in the top left corner of every graph inspector.
uint
graphIndex
Index of the graph, used for identification purposes.
Used as an ID of the graph, considered to be unique.
NoteThis is Pathfinding.Util.Guid not System.Guid. A replacement for System.Guid was coded for better compatibility with iOS
bool
infoScreenOpen
Used in the editor to check if the info screen is open.
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. Version 3.0.8.1 was released because of this bug only
uint
initialPenalty
Default penalty to apply to all nodes.
string
name
Name of the graph.
Can be set in the unity editor
bool
open
Is the graph open in the editor.
bool
persistent
True if the graph will be included when serializing graph data.
If false, the graph will be ignored when saving graph data.
Most graphs are persistent, but the LinkGraph is not persistent because links are always re-created from components at runtime.
bool
showInInspector
True if the graph should be visible in the editor.
False is used for some internal graph types that users don't have to worry about.
Private/Protected Members
int | size | |
out JobHandle | dependency | |
)
void
AssertSafeToUpdateGraph
()
Throws an exception if it is not safe to update internal graph data right now.
It is safe to update graphs when graphs are being scanned, or inside a work item. In other cases pathfinding could be running at the same time, which would not appreciate graph data changing under its feet.
void
CalculateDimensions
(
out int | width | |
out int | depth | |
out float | nodeSize | |
)
Calculates the width/depth of the graph from unclampedSize and nodeSize.
The node size may be changed due to constraints that the width/depth is not allowed to be larger than 1024 (artificial limit).
bool
ClipLineSegmentToBounds
(
)
Clips a line segment in graph space to the graph bounds.
That is (0,0,0) is the bottom left corner of the graph and (width,0,depth) is the top right corner. The first node is placed at (0.5,y,0.5). One unit distance is the same as nodeSize.
Returns false if the line segment does not intersect the graph at all.
void
CreateNavmeshSurfaceVisualization
(
)
Draw the surface as well as an outline of the grid graph.
The nodes will be drawn as squares (or hexagons when using neighbours = Six).
long
CrossMagnitude
(
)
Magnitude of the cross product a x b.
void
DeserializeNativeData
(
)
void
DeserializeNodeSurfaceNormals
(
)
void
DestroyAllNodes
()
Destroys all nodes in the graph.
WarningThis is an internal method. Unless you have a very good reason, you should probably not call it.
void
DirtyBounds
(
)
Notifies the system that changes have been made inside these bounds.
This should be called by graphs whenever they are changed. It will cause off-mesh links to be updated, and it will also ensure GraphModifier events are callled.
The bounding box should cover the surface of all nodes that have been updated. It is fine to use a larger bounding box than necessary (even an infinite one), though this may be slower, since more off-mesh links need to be recalculated. You can even use an infinitely large bounding box if you don't want to bother calculating a more accurate one. You can also call this multiple times to dirty multiple bounding boxes.
When scanning the graph, this is called automatically - with the value from the bounds property - for all graphs after the scanning has finished.
void
DisposeUnmanagedData
()
Cleans up any unmanaged data that the graph has.
NoteThe graph has to stay valid after this. However it need not be in a scanned state.
void
DrawUnwalkableNodes
(
DrawingData | gizmos | |
float | size | |
RedrawScope | redrawScope | |
)
List<GraphNode>
GetNodesInRegion
(
)
All nodes inside the shape or if null, the bounding box.
If a shape is supplied, it is assumed to be contained inside the bounding box.
void
HandleBackwardsCompatibility
(
)
const int
HexagonConnectionMask = 0b010101111
Mask based on hexagonNeighbourIndices.
This indicates which connections (out of the 8 standard ones) should be enabled for hexagonal graphs.
int hexagonConnectionMask = 0;
for (int i = 0; i < GridGraph.hexagonNeighbourIndices.Length; i++) hexagonConnectionMask |= 1 << GridGraph.hexagonNeighbourIndices[i];
void
OnDestroy
()
Function for cleaning up references.
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). Use for any cleanup code such as cleaning up static variables which otherwise might prevent resources from being collected. Use by creating a function overriding this one in a graph class, but always call base.OnDestroy () in that function. All nodes should be destroyed in this function otherwise a memory leak will arise.
void
PostDeserialization
(
)
Called after all deserialization has been done for all graphs.
Can be used to set up more graph data which is not serialized
)
Internal method to scan the graph.
Override this function to implement custom scanning logic.
IGraphUpdatePromiseIUpdatableGraph.
ScheduleGraphUpdates
(
)
Internal function to update the graph.
void
SerializeNodeSurfaceNormals
(
)
int[]
allNeighbourIndices = { 0, 1, 2, 3, 4, 5, 6, 7 }
Which neighbours are going to be used when neighbours=8.
int[]
axisAlignedNeighbourIndices = { 0, 1, 2, 3 }
Which neighbours are going to be used when neighbours=4.
bool
exists
True if the graph exists, false if it has been destroyed.
int[]
hexagonNeighbourIndices = { 0, 1, 5, 2, 3, 7 }
Which neighbours are going to be used when neighbours=6.
System.Func<GridNodeBase>
newGridNodeDelegate = () => new GridNode()
Delegate which creates and returns a single instance of the node type for this graph.
This may be set in the constructor for graphs inheriting from the GridGraph to change the node type of the graph.
Internal data for each node.
It also contains some data not stored in the node objects, such as normals for the surface of the graph. These normals need to be saved when the maxStepUsesSlope option is enabled for graph updates to work.
bool
useRaycastNormal
Use heigh raycasting normal for max slope calculation.
True if maxSlope is less than 90 degrees.
Deprecated Members
void
CalculateConnections
(
)
Calculates the grid connections for a single node.
Convenience function, it's slightly faster to use CalculateConnections(int,int) but that will only show when calculating for a large number of nodes. This function will also work for both grid graphs and layered grid graphs.
void
CalculateConnections
(
)
Calculates the grid connections for a single node.
Note that to ensure that connections are completely up to date after updating a node you have to calculate the connections for both the changed node and its neighbours.
In a layered grid graph, this will recalculate the connections for all nodes in the (x,z) cell (it may have multiple layers of nodes).
bool
Linecast
(
Vector3 | from | Point to linecast from |
Vector3 | to | Point to linecast to |
GraphNode | hint | This parameter is deprecated. It will be ignored. |
)
Returns if there is an obstacle between from and to on the graph.
This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
var gg = AstarPath.active.data.gridGraph;
bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position);
DeprecatedThe hint parameter is deprecated
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
bool
Linecast
(
)
Returns if there is an obstacle between from and to on the graph.
This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
var gg = AstarPath.active.data.gridGraph;
bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position);
DeprecatedThe hint parameter is deprecated
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
bool
Linecast
(
Vector3 | from | Point to linecast from |
Vector3 | to | Point to linecast to |
GraphNode | hint | This parameter is deprecated. It will be ignored. |
outGraphHitInfo | hit | Contains info on what was hit, see GraphHitInfo |
List<GraphNode> | trace | If a list is passed, then it will be filled with all nodes the linecast traverses |
System.Func<GraphNode, bool> | filter=null | If not null then the delegate will be called for each node and if it returns false the node will be treated as unwalkable and a hit will be returned. Note that unwalkable nodes are always treated as unwalkable regardless of what this filter returns. |
)
Returns if there is an obstacle between from and to on the graph.
This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
var gg = AstarPath.active.data.gridGraph;
bool anyObstaclesInTheWay = gg.Linecast(transform.position, enemy.position);
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
DeprecatedThe hint parameter is deprecated
bool
SnappedLinecast
(
)
Returns if there is an obstacle between from and to on the graph.
This function is different from the other Linecast functions since it snaps the start and end positions to the centers of the closest nodes on the graph. This is not the same as Physics.Linecast, this function traverses the graph and looks for collisions.
VersionSince 3.6.8 this method uses the same implementation as the other linecast methods so there is no performance boost to using it.
In 3.6.8 this method was rewritten and that fixed a large number of bugs. Previously it had not always followed the line exactly as it should have and the hit output was not very accurate (for example the hit point was just the node position instead of a point on the edge which was hit).
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
float
maxClimb
The max y coordinate difference between two nodes to enable a connection.
float
penaltyAngleFactor = 100F
How much penalty is applied depending on the slope of the terrain.
At a 90 degree slope (not that exactly 90 degree slopes can occur, but almost 90 degree), this penalty is applied. At a 45 degree slope, half of this is applied and so on. Note that you may require very large values, a value of 1000 is equivalent to the cost of moving 1 world unit.
float
penaltyAnglePower = 1
How much extra to penalize very steep angles.
bool
penaltyPosition
Use position (y-coordinate) to calculate penalty.
DeprecatedUse the RuleElevationPenalty class instead
float
penaltyPositionFactor = 1F
Scale factor for penalty when calculating from position.
float
penaltyPositionOffset
Offset for the position when calculating penalty.
DeprecatedUse the RuleElevationPenalty class instead
Holds settings for using a texture as source for a grid graph.
Texure data can be used for fine grained control over how the graph will look. It can be used for positioning, penalty and walkability control.
Below is a screenshot of a grid graph with a penalty map applied. It has the effect of the AI taking the longer path along the green (low penalty) areas.
Color data is got as 0...255 values.
A* Pro FeatureThis is an A* Pathfinding Project Pro feature only. This function/class/variable might not exist in the Free version of the A* Pathfinding Project or the functionality might be limited.
The Pro version can be bought here
WarningCan only be used with Unity 3.4 and up
DeprecatedUse the RuleTexture class instead