Scanning graph in a run time.
Hi
I m trying to scan the graphs in my scene in at runtime using
AstarPath.active.Scan ()
It generates spike in my frame rate. Is there a way for my to scan only one graph (from what I understand Scan() scans all of them) or/and move the graph scanning to the other thread. I tried adjusting max frame time variable in the inspector but it didn’t seem to change anything.
Hi
Scanning a graph is slow, you cannot get around that.
You can update smaller parts of the graph if you are only modifying parts of it.
The graph scanning cannot be moved to a separate thread because it needs to call unity api methods, and unity will crash if they are called from a separate thread.
Though you can actually scan only one graph per frame.
`public void Start () {
StartCoroutine ( ScanAllGraphs ());
}
public IEnumerator ScanAllGraphs () {
foreach (AstarPath.active.ScanLoop()) {
yield return null;
}
}`
Hi
Well i was able to force single graph update with the small custom modification.
AstarPath:
`
public int getGraphid( NavGraph graph ) {
for ( int i=0; i < graphs.Length; i++ ) {
if ( graphs[ i ] == graph ) return i;
}
return -1;
}
`
` public void ScanLoop( OnScanStatus statusCallback, int graphId = -1 ) {
....
for (int i=0;i<graphs.Length;i++) {
if( graphId == i || graphId == -1 ) {
if (graphs[i] != null ) {
graphs[i].GetNodes (delegate (GraphNode node) {
node.Destroy ();
return true;
});
}
}
}
for (int i=0;i<graphs.Length;i++) {
if ( graphId == i || graphId == -1 ) {
....
}
`
It helped a lot and it seams nothing has been broken. Is there maybe something I haven’t noticed?
It is still a bit too slow for what I’ trying to achieve. Updating small parts of the graph doesn’t help much because, I‘ve created the graph from the script and it tells me to scan it first before I will start updating.
I tried to move the scanning to the separate thread but I bumped into the problem you’ve described. Now I’m thinking about dividing the scanning function in to parts and executing it in the update function. Will that approach work? Is there something I should know about?
Hi
Yes, that approach can work. In fact I have been thinking about doing the same thing.
What you can do is to make the ScanInternal method a coroutine (i.e it returns an IEnumerator) and use the yield statement in it. In the ScanLoop method you simple iterate through the whole ScanInternal method while scanning. Then you can use the approach I mentioned above to do only a small part per frame.
Works like a dream Thanks