- A* version: [5.2.5]
- Unity version: [6000.0.22f1]
Hi,
I posted about this yesterday over here:
Create a PointGraph manualy - General / Point graph - Support Forum
But tealtxgr advised me to make a new topic for it…
I have created this method to create nodes and setup connections between them at runtime and in the editor. It works fine when i disable optimizeForSparseGraph but with optimizeForSparseGraph enabled it only works after I call this method the second time at runtime or in the editor from a custom editor button. The first scan always fails.
I’m guessing it has something to do with the lookupTree not being initialized in the Pointgraph.BuildNodeLookup function but I’m not sure…
Is there any method that I need to call before creating the nodes that would otherwise be done by the Scan() method?
For now I’ll keep optimizeForSparseGraph off but any help in getting it to work with optimizeForSparseGraph enabled would be appreciated!
Cheers
The error:
NullReferenceException: Object reference not set to an instance of an object
Pathfinding.PointGraph.AddNode[T] (T node, Pathfinding.Int3 position) (at ./Packages/com.arongranberg.astar/Graphs/PointGraph.cs:327)
Pathfinding.PointGraph.AddNode (Pathfinding.Int3 position) (at ./Packages/com.arongranberg.astar/Graphs/PointGraph.cs:291)
TDXPointGraph+<>c__DisplayClass6_0.<ScanPointGraph>b__0 (Pathfinding.IWorkItemContext ctx) (at Assets/MyGame/Scripts/Pathfinding/TDXPointGraph.cs:174)
Pathfinding.WorkItemProcessor.ProcessWorkItems (System.Boolean force, System.Boolean sendEvents) (at ./Packages/com.arongranberg.astar/Core/Misc/WorkItemProcessor.cs:344)
Pathfinding.WorkItemProcessor.ProcessWorkItemsForUpdate (System.Boolean force) (at ./Packages/com.arongranberg.astar/Core/Misc/WorkItemProcessor.cs:423)
AstarPath.PerformBlockingActions (System.Boolean force) (at ./Packages/com.arongranberg.astar/Core/AstarPath.cs:875)
AstarPath.FlushWorkItems () (at ./Packages/com.arongranberg.astar/Core/AstarPath.cs:1131)
TDXPointGraph.ScanPointGraph () (at Assets/MyGame/Scripts/Pathfinding/TDXPointGraph.cs:211)
TDXPointGraph.Start () (at Assets/MyGame/Scripts/Pathfinding/TDXPointGraph.cs:19)
My method:
public void ScanPointGraph()
{
PointGraph pointGraph = AstarPath.active.data.pointGraph;
pointGraph.RebuildNodeLookup();
pointGraph.RebuildConnectionDistanceLookup();
AstarPath.active.AddWorkItem(new AstarWorkItem(ctx =>
{
// Create and initialize nodes
for (int i = 0; i < navNodesChunks.Length; i++)
{
for (int j = 0; j < navNodesChunks[i].navNodes.Length; j++)
{
if (navNodesChunks[i].navNodes[j] != null)
{
// Initialize the graphNode if necessary
if (navNodesChunks[i].navNodes[j].pointNode == null)
{
navNodesChunks[i].navNodes[j].pointNode = pointGraph.AddNode((Int3)navNodesChunks[i].navNodes[j].transform.position);
}
}
}
}
pointGraph.RebuildNodeLookup();
// Set up connections between nodes
for (int i = 0; i < navNodesChunks.Length; i++) // For each chunck
{
// For each navNode in the chunck
for (int j = 0; j < navNodesChunks[i].navNodes.Length; j++)
{
NavNode currentNode = navNodesChunks[i].navNodes[j];
if (currentNode != null)
{
ConnectToNeighbor(currentNode, currentNode.neighborFront);
ConnectToNeighbor(currentNode, currentNode.neighborBack);
ConnectToNeighbor(currentNode, currentNode.neighborLeft);
ConnectToNeighbor(currentNode, currentNode.neighborRight);
}
}
}
pointGraph.RebuildConnectionDistanceLookup();
}));
AstarPath.active.FlushWorkItems();
GraphUpdateScene[] graphUpdateScenes = FindObjectsByType<GraphUpdateScene>(FindObjectsSortMode.None);
for(int i=0; i<graphUpdateScenes.Length; i++)
if(graphUpdateScenes[i].applyOnScan) graphUpdateScenes[i].Apply();
AstarPath.active.FlushGraphUpdates();
}
private void ConnectToNeighbor(NavNode node, NavNode neighbor)
{
if (node != null && node.pointNode != null && neighbor != null && neighbor.pointNode != null)
{
if (!node.pointNode.ContainsOutgoingConnection(neighbor.pointNode))
{
var cost = (uint)(node.pointNode.position - neighbor.pointNode.position).costMagnitude;
GraphNode.Connect(node.pointNode,neighbor.pointNode, cost);
}
}
}