Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Some NavMeshLinks do not connect until object is moved

Discussion in 'Navigation' started by sSaltyDog, Jan 6, 2020.

  1. sSaltyDog

    sSaltyDog

    Joined:
    Mar 4, 2017
    Posts:
    37
    I'm generating NavMeshes using the Unity High Level Workflow:
    https://github.com/Unity-Technologies/NavMeshComponents

    Certain links will not connect (the ones without the light blue rectangle below)


    As you can see by the orange highlight, the terrain is separated into areas each with their own GameObject Mesh, GameObject and NavMesh. I generate all of these before generating the links:

    Code (CSharp):
    1. for(Sector s in sectors)
    2. {
    3.     GenerateNavMesh(s);
    4. }
    5.  
    6. for(Sector s in sectors)
    7. {
    8.     GenerateLinks(s);
    9. }
    10.  
    When the mesh objects are generated in a random order, a few specific links will work or not work, seemingly at random. Generating the objects in a consistent order seems to yield consistent failures in connection. So it seems as though the order in which the objects are generated has some impact on which links fail.

    Lastly, changing the position (on any axis) of the object either side of a failed link (by dragging in the editor window) will cause the link to immediately connect. After resetting the transform of that object, the link stays connected.

    Apologies if I'm missing something obvious here, I'm fairly new to Unity NavMesh.

    Thanks
     
  2. sSaltyDog

    sSaltyDog

    Joined:
    Mar 4, 2017
    Posts:
    37
    Kind of fixed it but still not sure what the issue or proper solution is..

    I tried creating the Meshes and NavMeshes on Awake() and adding the NavMeshLinks on Start(), this didn't resolve the issue.

    However, moving the NavMeshLink creation from Start() to Update() (and hacking it with a bool to only execute once) seems to get me perfect links every time.

    I'm guessing there is some issue where certain NavMeshes aren't considered to exist when creating the links? That seems strange to me though, I would have though simply creating the links after the meshes would be fine.

    Still interested to hear any advice/ideas about what might be wrong here.
     
  3. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    The NavMesh is generated asynchronously which leads to your problems.
    Look for
    NavMeshBuilder.UpdateNavMeshDataAsync(...) 
    in NavMeshComponents code.
    This function returns an
    AsyncOperation
    . As soon as this operation is finished you can start creating your links.

    Hope that helps.
     
    sSaltyDog likes this.
  4. sSaltyDog

    sSaltyDog

    Joined:
    Mar 4, 2017
    Posts:
    37
    Ah, now everything makes sense. :)

    Thanks!
     
  5. sSaltyDog

    sSaltyDog

    Joined:
    Mar 4, 2017
    Posts:
    37
    Updating this in case it's useful to someone:

    I've adjusted how I'm creating NavMesh. Previously I was using NavMeshSurface, creating an instance per mesh object. However it seems I had made a mistake, that isn't what it's for. The ReadMe describes it as:
    for building and enabling a NavMesh surface for one agent type.

    I'm not entirely sure what was going wrong before but I'm guessing it was related to my use of NavMeshSurface alongside NavMesh.AddLink(). I am now using NavMesh.AddNavMeshData to add new terrain navmeshes.

    The only outstanding issue I see is that, on stopping play mode, I get a warning:
    Removed <total number of links> instances of leaked navmesh links while exiting play-mode.
    This has been happening all along.

    Here's how I'm generating NavMeshes per terrain chunk now:

    Code (CSharp):
    1. public static void GenerateNavMesh(float3 meshPosition, MeshFilter meshFilter, Bounds bounds)
    2.     {
    3.         Mesh mesh = meshFilter.sharedMesh;
    4.         NavMeshBuildSettings settings = NavMesh.GetSettingsByID(0);
    5.         List<NavMeshBuildSource> sources = NavMeshSource(mesh, meshFilter);
    6.         NavMeshData data = NavMeshBuilder.BuildNavMeshData(settings, sources, bounds, float3.zero, Quaternion.identity);
    7.         NavMesh.AddNavMeshData(data, meshPosition, Quaternion.identity);
    8. }
    The bounds is just mesh.bounds.

    And here's how I was always adding NavMeshLinks:

    Code (CSharp):
    1. var data = new NavMeshLinkData();
    2. data.width = ...
    3. data.startPosition = ...
    4. data.endPosition = ...
    5. NavMesh.AddLink(data);
    This seems to work perfectly. Every time I generate a new section of terrain, I generate all links to connecting sections and set NavMeshLinkData.bidirectional to false so I don't get any duplicates. This includes generating one way links to navmeshes that haven't been generated yet. Once the adjacent navmesh has been generated, the link connects normally.

    It's worth noting that I've also changed how I am fundamentally generating the terrain. Previously I was generating an X by X area all at once. Now I am generating it chunk by chunk as the player entity moves around.