Thanks for getting in touch so quickly Aron!
Below is a raw visual of an example situation in which i’ve mark some locations I’d like to be able to determine as dead-ends.
I wonder if you’d recommend using another graph type altogether to allow for an easier analysis?
I have assessed your idea about watershed and I can see its merits - and agree about the potentially tedious implementation you mentioned.
I have avoided changing the node-width in the AstarPath component when generating graphs as i’m quite content with the density which it is currently generating as it will allow for a non-uniform corridor width which I intend to support.
A feature of the procedural level generation is that it IS strictly tile based - so I’ve been thinking it should be possible to quantise the grid nodes generated by your project such that all nodes with a position within a single tile area are ‘collated’.
I’ve made some progress with this and am pleased with the initial results… however I’ve hit a snag which I hoped you could shed some light on.
Below is a snap shot of the progress to date:
Cyan Dots: Center of QuantizedNode instances created
Magenta Dots: NavGraph::Nodes[] which belong to QuantizedNode
What i’ve done here is execute a FindDeadEnds method that creates a List<>. I invoke this in response by subscribing to AstarPath delegates:
-OnLatePostScan
-OnGraphsUpdated
Assumption: I am assuming all Node::connections are populated at this point! Is this Wrong?
The QuantizedNodes class used looks as follows:
`
public class QuantizedNode
{
//center of the grid tile the nodes belong to
public readonly Vector3 searchCenter;
//quantizedNodeIndex - ref for remapping node connections to QuantizedNode connections
public readonly int nodeIndex;
//object that represents this node in world space
public GameObject markerObject;
//list of NavGraph::nodes that are stored and used to create the QuantizedNode with useable connections
public List<Node> nodes = new List<Node>();
//a list of the other quantized nodes to which this one is connected
public List<QuantizedNode> connections = new List<QuantizedNode>();
//adds a connected QuantizedNode to be connected to this one
public void AddConnection(QuantizedNode qn)
{
//dont add connections to self!
if(qn == this) return;
connections.Add(qn);
}
//ctor
public QuantizedNode(int nodeIndex, Vector3 searchCenter)
{
//cache node index
this.nodeIndex = nodeIndex;
//cache center of area
this.searchCenter = searchCenter;
}
//returns the centeral position of the walkable nodes that belong to this QuantizedNode
public Vector3 walkableCenter
{
get
{
Vector3 vec = Vector3.zero;
for(int i = 0; i < nodes.Count; i++)
vec += (Vector3)nodes[i].position;
vec /= nodes.Count;
return vec;
}
}
}
`
The logic for the method that builds and processes graph::nodes to build the List<> follows - however it is failing as every Node being processed has a null connections array at the time of being processed.
`
//for every walkable node in graph.nodes
↳//round nodes position to nearest tile center
//assign node to instance of QuantizedNode::nodes[] based of rounded pos
//also add entry to temp Dictionary<Node, int> to lookup a nodes parent for quick redirect when building QuantizedNode connections based of its nodes
//process each QuantizedNode to build its connections to other QuantizedNodes based on the connections of the Nodes it contains
//foreach QuantizedNode in quantizedNodesList
↳//foreach Node in QuantizedNode::nodes
↳//if node hasn't any connections (node::connections==null OR ::Length==0
↳//node::UpdateConnections
**↳//if node STILL no connections -> process next node in QuantizedNode::nodes
(** = always failing here!)
//if node was found to have connections
↳//foreach node in node::connections
↳//if the node ins't walkable -> skip process next node in node::connections
↳//if there is a QuantizedNode lookup value for the Node being processed
//get the connectionIndex (QuantizedNode::nodeIndex) that contains this Node
//add the QuantizedNode with QuantizedNode::nodeIndex == connectionIndex to QuantizedNode being processed
`
As the image shows the process is working pretty well. There are issues present due to my test world layout not strictly adhering to the tile sizes i’m passing to the system. However clearly the Node::connections haven’t been constructed at this time after AstarPath::OnLatePostScan & AstarPath::OnGraphsUpdated.
Could you please let me know what I might be doing wrong here?
Many Thanks Aron.