Adding custom nodes to point graphs

Introduction

The Point graph is a type of graph that is created from a set of points in space. Each node is a single point, and the nodes can have connections between each other.

In some cases you may want to create a point graph completely using code, by adding all nodes and connections manually.

See

If you want even more customization, you can write a custom graph type: Writing Graph Generators.

Adding nodes to a point graph

To add nodes to a point graph, you can use the PointGraph.AddNode method. This must be done during a graph update, for safety.

// This holds all graph data
AstarData data = AstarPath.active.data;

// This creates a Point Graph
PointGraph graph = data.AddGraph(typeof(PointGraph)) as PointGraph;

AstarPath.active.Scan(graph);

// Make sure we only modify the graph when all pathfinding threads are paused
AstarPath.active.AddWorkItem(() => {
// Add 2 nodes and connect them
var node1 = graph.AddNode((Int3) new Vector3(1, 2, 3));
var node2 = graph.AddNode((Int3) new Vector3(4, 5, 6));
var cost = (uint)(node2.position - node1.position).costMagnitude;
GraphNode.Connect(node1, node2, cost);
});

// Run the above work item immediately
AstarPath.active.FlushWorkItems();

Note

Scanning a point graph will recalculate it from scratch, and discard any custom nodes you may have added.

If you don't want to calculate the node connections yourself, you can use a graph update object to do it for you. This code will recalculate all connections around the node, and connect it to other nodes using the graph's settings.

AstarPath.active.AddWorkItem(() => {
var node = graph.AddNode((Int3) new Vector3(1, 2, 3));
// Recalculate all connections around the node
AstarPath.active.UpdateGraphs(new Bounds((Vector3)node.position, Vector3.one*0.1f));
});

// Run the above updates immediately
AstarPath.active.FlushWorkItems();
AstarPath.active.FlushGraphUpdates();

Removing nodes from a point graph

You can also remove nodes using the PointGraph.RemoveNode method.

// Make sure we only modify the graph when all pathfinding threads are paused
PointNode node1 = null;
PointNode node2 = null;
AstarPath.active.AddWorkItem(() => {
// Add 2 nodes and connect them
node1 = graph.AddNode((Int3) new Vector3(1, 2, 3));
node2 = graph.AddNode((Int3) new Vector3(4, 5, 6));
var cost = (uint)(node2.position - node1.position).costMagnitude;
GraphNode.Connect(node1, node2, cost);
});

// ...

AstarPath.active.AddWorkItem(() => {
// Remove the nodes
graph.RemoveNode(node1);
graph.RemoveNode(node2);
});

Associating nodes with GameObjects

If you want to associate your custom nodes with GameObjects, you can use the PointNode.gameObject field:

// Associate a GameObject with a node
var node = graph.AddNode((Int3) new Vector3(1, 2, 3));
node.gameObject = gameObject;
Later you can retrieve the GameObject from the node like this:

var node = AstarPath.active.GetNearest(transform.position).node;
var pointNode = node as PointNode;

if (pointNode != null) {
Debug.Log("That node was created from the GameObject named " + pointNode.gameObject.name);
} else {
Debug.Log("That node is not a PointNode");
}

Associating nodes with custom data

If you want to add more custom data to your point nodes, you can create a subclass of the PointNode class.

class CustomPointNode : PointNode {
// Some custom data to store on the node
public int importantAnswer;

public CustomPointNode(AstarPath active) : base(active) {}
}

void AddCustomPointNode () {
AstarPath.active.AddWorkItem(() => {
var graph = AstarPath.active.data.pointGraph;
graph.AddNode(new CustomPointNode(AstarPath.active) {
importantAnswer = 42
}, (Int3) new Vector3(1, 2, 3));
});
}

Warning

Nodes created in this way cannot be serialized (see Saving and Loading Graphs).