How to increase performance of LoadTile()?

Hello Aron,
I am struggling with performance problems with LoadTile(). My game is very large and is split into terrain prefabs that load dynamically. Each prefab is 1000 by 1000 units and is further split into 5x5=25 Tiled Recast Graphs. My system functionally works, but the problem is performance. At any one time, 9 of the 1000by1000 tiles can be loaded.

Here is my code that calls LoadTile(). I overloaded TileHandler RegisterTileType

public void LoadNavMesh()
{
    if ((!Application.isPlaying) || (AstarPath.active == null))
        return;
   
    Int3 centerOffset = new Int3(0, 0, 0);
    Int3 tileSize = new Int3(0, 0, 0);

    for (int i = 0; i < tileTypes.Count; i++) //25 tiles total
    {
        TileHandler.TileType tp = new TileHandler.TileType(tileTypes[i].verts, tileTypes[i].tris, tileSize, centerOffset, tileTypes[i].width, tileTypes[i].depth);
        handler.RegisterTileType(tp);
        handler.LoadTile(tp, tileTypes[i].xGlobalTileIndex, tileTypes[i].zGlobalTileIndex, 0, tileTypes[i].yGlobalTileOffset);
    }
}

There is a long 2 second loading hitch when using LoadTile(). I’ve tried using RecastGraph.StartBatchTileUpdate() and TileHandler.StartBatchLoad() but it doesn’t seem to have any effect. I’ve tracked the few lines of code that are causing the slowdown in RecastGenerator.cs
Line 1890: tile.bbTree.Insert (node);
Line 1919: for (int i=0;i<nodes.Length;i++) nodes[i].GraphIndex = (uint)graphIndex;

Is there an alternate way to load tiles in, maybe by grouping 25 at a time? Or maybe somehow change the calculation intensive functions to be a Coroutine to spread the load over time?

To get an idea for the performance problem; load the initial 9 tiles with navmeshes it takes 34 seconds. Whereas it only takes 8 seconds without any navmeshes. I’m using v3.6.8

Thanks so much,
-Mark

Sorry for the late answer.

2 seconds??

That is a lot. In my tests it is usually done in a few milliseconds.

Since it takes such a long time in bbTree.Insert I am wondering if maybe there are some degenerate nodes in the mesh.
Check if there are any duplicate triangles or triangles where all points are colinear (i.e they lie on the same line).

How many triangles do you have in each of those tiles?

The navmesh looks clean, I could not find any problems. I wrote a script that checks for duplicate triangles and uses AstarMath.isColinearAlmost. I verified functionally by intentionally adding some degenerate node data.

Here is a printout of the most detailed nav of a city area. The recastgraph is 1000x1000 units which is further broken into 25 TilesTypes:

Tile 0: tris=528: verts=168
Tile 1: tris=483: verts=152
Tile 2: tris=369: verts=115
Tile 3: tris=1719: verts=553
Tile 4: tris=363: verts=119
Tile 5: tris=3174: verts=996
Tile 6: tris=1830: verts=585
Tile 7: tris=4422: verts=1398
Tile 8: tris=3021: verts=991
Tile 9: tris=1818: verts=584
Tile 10: tris=3819: verts=1195
Tile 11: tris=2370: verts=778
Tile 12: tris=1752: verts=554
Tile 13: tris=5304: verts=1726
Tile 14: tris=279: verts=82
Tile 15: tris=2835: verts=911
Tile 16: tris=3375: verts=1097
Tile 17: tris=2151: verts=642
Tile 18: tris=18: verts=8
Tile 19: tris=552: verts=176
Tile 20: tris=6000: verts=1932
Tile 21: tris=2106: verts=649
Tile 22: tris=2577: verts=809
Tile 23: tris=3993: verts=1230
Tile 24: tris=207: verts=111

totalTris= 55065 totalVerts=17561

The main problem is that the bbTree calculation is blocking the main Unity thread and making my game lock up. Would it be possible to put it into a separate thread so its non-blocking? It seems your asset uses multi-threading, but I am clueless how to utilize it.

Ideally I would spread the calculation over 5-10 seconds and my AI logic would just sit tight until the nav is loaded.

Hi

Do you think it would be possible to share your project with me?
It really shouldn’t take that long to calculate so there must be some very high computational complexity code that it is triggering. Having a reproducible test case would help a lot.

Multithreading is mostly used for pathfinding calculation, not during scan time.
Recast graphs can use a separate thread when recalculating whole tiles, however there is currently no support for using LoadTile in a separate thread.

Sure! Can your email support 34GB zip file? :slight_smile: Just kidding. I will condense my project down so it’s a barebones example of loading the graphs

:smiley: Ok. Just send me a PM when you are ready.