Search Unity

UpdateNavMeshDataAsync fails on editor time Navmesh

Discussion in 'Navigation' started by BTables, May 3, 2017.

  1. BTables

    BTables

    Joined:
    Jan 18, 2014
    Posts:
    61
    Trying to do asynchronous updates of Navmesh objects at runtime that were built at editor time.

    Our maps are big, contain thousands on objects, and mostly static. Baking takes ~ 5 mins.

    Players can build bases, those bases need to update the navmesh tile they are in.

    First issue is that doing a runtime navmesh update on a NavMeshData asset that was built at editor time clears out the entire navmesh and refuses to re add anything (also takes roughly the amount of time it takes to rebake the whole thing but with no results)

    If I create a new navmesh at runtime then call updatenavmesh it works as expected and is very fast.

    I tried instantiating the navmesh data object so I'm not messing with the project asset but this didn't help.

    Regenerating a navmesh for 3 mins on server startup isn't really feasible.

    The second issue with this process is that I have to pack thousands of rock transforms into the sources list for an update of a single tile that concerns only a few colliders. And this array will constantly have things added and removed, requiring me to re allocate a massive array and re copy all my static sources into it just to update one cell.

    Has anyone come up with a decent solution to this?
     
  2. BTables

    BTables

    Joined:
    Jan 18, 2014
    Posts:
    61
    @Jakob_Unity could I please get some insight into this? Is runtime updating of an editor created navmesh not possible?
     
  3. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    It is possible - with the restriction that you need to pass all the sources when updating.
     
  4. BTables

    BTables

    Joined:
    Jan 18, 2014
    Posts:
    61
    Thanks for the reply.

    In the first scenario, ignoring the problem of collating sources, I am passing all sources in the scene to an UpdateNavMesh call, it simply clears out the navmesh and takes as long as it takes to bake an entirely new scene navmesh with no results at the end.

    It's as if the hash that is stored with the editor time Navmesh for each source gets calculated differently at runtime. If this isn't expected behaviour I can provide a repro project.
     
  5. BTables

    BTables

    Joined:
    Jan 18, 2014
    Posts:
    61
    So creating the reproduction case I couldn't reproduce the issue from before. The updates seem to be doing as expected. They are significantly faster than re-creating the entire Navmesh, but seem to have a very large blocking operation on the main thread under Navmesh.Integrate.UpdateSurface.

    The testbed I have created is a very large scene to be used as a worst case, its currently 10km x 10km with about 2000 cubes as sources.

    NavmeshPerf.png

    The above screenshot is of performance of issuing a NavMeshUpdate with only 1 1x1 cube being moved less than a 1 unit. I would expect the NavMesh system to be able to isolate the operation to a single tile and perform the update without issue.

    In contrast, the NavMesh obstacle can carve easily without any visible performance cost.

    Currently our only option is just carving out a no-walk zone where player constructions are which sucks. Is doing runtime recalculation going to be feasible in the near future?
     
  6. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    Hm - i'll have a look. `LogStringToConsole` suggests smth is being logged (do you see 144 errors/warnings in console) - if so, what's the report ?
     
  7. BTables

    BTables

    Joined:
    Jan 18, 2014
    Posts:
    61
    So I went back into my failed reproduction scene to see what was going on, and turns out I wasn't crazy. Same issue I was having originally trying to rebake at runtime, getting bogus results that take ages.

    As for your question, the console logs were warnings from 114 navmesh agents that were too far from the navmesh, which seemed to re-issue the warnings whenever a navmesh update was applied. Removing all of these NavmeshAgents had no effect on the 1.8 second blocking time at the end of the operation.

    What I also discovered with this round of testing, was that to reproduce the issue of trying to rebake a navmesh asset at runtime that was baked previously, you need to do the following:

    Bake a NavMesh in a scene at editor time (so you get the subfolder with the scene name, and a Navmesh-Gameobject name asset)
    Save Scene
    Create a new scene
    Load original scene
    Run scene
    Issue a Navmesh Update
    Stop scene
    Save scene
    Create new scene
    Load original scene
    Run scene
    Issue a Navmesh Update

    What is happening is on the second load of the scene, the entire navmesh is rebaking not just the update tile. Then the navmesh that is output is offset by the exact amount that the NavmeshSurface object is offset from the origin.

    Its hard to tell exactly whats going on here, but it looks like the initial runtime updates to the navmesh are being written to the asset at runtime. Which is a little weird but workable, but then when it gets re-written back to the asset, it loses the offset information from its original NavMeshSurface object. Then next time its updated, the offset from origin is doubled, making it think all the sources have moved by that amount and rebakes the entire scene.

    Attached is my repo project, I cleaned up the level to be much smaller, its still a bit messy.

    To issue the runtime update, simply move the rebaker object and tick Issue Rebake.

    The initialize tickbox will trash the old navmesh and build a new one at runtime.
     

    Attached Files: