Search Unity

Update NavMesh at Runtime

Discussion in 'Navigation' started by emrys90, Jun 8, 2017.

  1. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    How do you update a nav mesh at runtime with the new API? I haven't been able to find any decent examples or documentation on it. For example, if I spawn in a new object after baking the nav mesh, how do I update the nav mesh in the area around that object so that it can be walked on/avoided?
     
  2. crimi

    crimi

    Joined:
    Jan 23, 2013
    Posts:
    6
    https://github.com/Unity-Technologies/NavMeshComponents/tree/master/Assets/Examples/Scripts

    Take those files.

    LocalNavMeshBuilder.cs && NavMeshSourceTag.cs

    LocalNavMeshBuilder = you setup the area
    NavMeshSourceTag = add to the floor/plane you want to bake the navmesh



    It does seem to work in some cases.

    As he stated in the video it does make sense to setup the LocalNavMeshBuilder Area first and at runtime add NavMeshSourceTag to your dynamic generated content.

    if you get the error message:

    Code (CSharp):
    1. Failed to create agent because it is not close enough to the NavMesh
    you can try to tweek the values in your navagent or make sure that you NPC/Player is really on the navmesh. i also experienced that there is a delay if you generate navmeshes at runtime so you could get those messages aswell.
     
    Last edited: Jun 9, 2017
    unity_ZUTqmbCABIuPGA likes this.
  3. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    That seems to be how to bake a nav mesh at runtime. What I'm trying to do is update a small part of it due to an object being instantiated/destroyed, without having to rebake the entire nav mesh.
     
  4. MrKilljoy

    MrKilljoy

    Joined:
    Aug 19, 2015
    Posts:
    9
    This is what I'm trying to do as well, since my project needs to regenerate parts of a destroyable terrain.
    Did you find a solution to your issue?
     
  5. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    @crimi Sorry, I guess I didn't pay attention to what you replied with. That's exactly what I'm looking for, thanks!
     
  6. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    My only other question then is how to do NavMeshSourceTag for colliders instead of only meshes. I looked at the API for NavMeshBuildSource and it seems to only allow you to either manually specify the dimensions of a primitive collider, or to use a mesh. Is there no way for it to instead just use a primitive collider?
     
  7. crimi

    crimi

    Joined:
    Jan 23, 2013
    Posts:
    6
    I did also figure out that you can change the script execution order.
    If you put those scripts LocalNavMeshBuilder.cs && NavMeshSourceTag.cs above the default time in the editor, they will execute first and you dont will have this error "Failed to create agent because it is not close enough to the NavMesh".

    https://docs.unity3d.com/Manual/class-ScriptExecution.html
     
    meowstudios likes this.
  8. GameDveloper09

    GameDveloper09

    Joined:
    Dec 24, 2015
    Posts:
    9
    i got this error when i try to use these scripts in scene
    "SetDestination" can only be called on an active agent that has been placed on a NavMesh.
     
    MishaMa likes this.
  9. Tsilliev

    Tsilliev

    Joined:
    Jan 21, 2014
    Posts:
    34
  10. bennett_apps

    bennett_apps

    Joined:
    Oct 9, 2018
    Posts:
    41
    The navmesh is used for "static" or unchanging objects. No movement, not being destroyed or added at runtime. If you want an object that changes, add a "navmesh obstacle" component to it, which when used properly allows the object to alter the mesh as it changes/moves/is disabled.
     
    vozcn likes this.
  11. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    I haven't had any issues updating the navmesh with the new NavMeshSurface component:

    Full rebuild from scratch (slow):
    Code (csharp):
    1. NavMeshSurface nm = GameObject.FindObjectOfType<NavMeshSurface>();
    2. nm.BuildNavMesh();
    Update only changed tiles (fast):
    Code (csharp):
    1. NavMeshSurface nm = GameObject.FindObjectOfType<NavMeshSurface>();
    2. nm.UpdateNavMesh(nm.navMeshData);
     
  12. Zante

    Zante

    Joined:
    Mar 29, 2008
    Posts:
    429
    Is there a reliable way to determine when the BuildNavMesh method has concluded?
     
    deivid-01 likes this.
  13. p02meysamghorbani

    p02meysamghorbani

    Joined:
    Jul 29, 2019
    Posts:
    3
  14. TomPo

    TomPo

    Joined:
    Nov 30, 2013
    Posts:
    86
  15. BigRookGames

    BigRookGames

    Joined:
    Nov 24, 2014
    Posts:
    330
    For anyone wondering, you need to add this to your project to gain access to the additional navmesh API calls: https://github.com/Unity-Technologies/NavMeshComponents
     
    ALIENPANDA and Keywise like this.
  16. Nelaha

    Nelaha

    Joined:
    Apr 3, 2020
    Posts:
    3
    Yeh... What mean changed tiles? Whole surface object as i see? I have flat 500x500units (tiled by 10x10) ground.
    And updating takes hundreds of milliseconds, so i have hube lag spike on it.

    Any way to make local changes faster?
     
  17. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    356
    Hi,

    You can look into
    Code (CSharp):
    1. nm.UpdateNavMesh(nm.navMeshData);
    It is using method
    Code (CSharp):
    1. var sources = CollectSources();
    That my be your bottleneck. Profile this method and create new, that suite your need (like nm.UpdateNavMeshLight(nm.navMeshData))
    As you can see, all you need is changed tiles, and call this method
    Code (CSharp):
    1. NavMeshBuilder.UpdateNavMeshDataAsync(data, GetBuildSettings(), sources, sourcesBounds);
     
    DungDajHjep likes this.
  18. Nelaha

    Nelaha

    Joined:
    Apr 3, 2020
    Posts:
    3
    Collect sources is takes only 0.5ms, 120ms takes WaitForJobGroupID. As i understand it must be async-multithread. But main thread stops, waiting for it.
     
  19. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    Changed tiles is the tiles in "Override Tile Size" on NavMeshSurface component. The navmesh has white lines showing the tiles.

    For example, I have a 512 and a 2k size terrain with 256 tile size. I use NavMeshObstacle with carving for trees that disappear and it does not hitch the game. I don't know how carving works compared to UpdateNavMesh.
     
    Last edited: Apr 11, 2020
  20. GB_Eliseev

    GB_Eliseev

    Joined:
    Jun 18, 2020
    Posts:
    1
    Hi! When changing settings, it takes a long time to generate . How do I solve this problem ?
    upload_2020-11-10_9-55-10.png
     
    Last edited: Nov 10, 2020
  21. bre_dev

    bre_dev

    Joined:
    Sep 14, 2015
    Posts:
    5
    Is there any update on this?

    I am encountering the same kind of issue.

    I am using the LocalNavmeshBuilder and the NavmeshSourceTag scripts, but with a bigger map it takes too much to recalculate the entire navmesh.

    Is there a way to update just one part of the navmesh which is around the object that gets added or destroyed?
     
    gillemp likes this.
  22. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,163
  23. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,163
    JasonBSteele likes this.
  24. CybeRock

    CybeRock

    Joined:
    Jul 14, 2021
    Posts:
    5
    your link doesn't seem to work

    so if you please may direct me to the solution..
     
  25. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,163
    To be blunt, There was a function UpdateNavMeshData
    https://docs.unity3d.com/ScriptReference/AI.NavMeshBuilder.UpdateNavMeshData.html

    And it take
    NavMeshBuildSettings
    as one of parameter
    https://docs.unity3d.com/2021.2/Documentation/ScriptReference/AI.NavMeshBuildSettings.html

    However, since 2020.1.0b9 https://unity3d.com/unity/beta/2020.1.0b9 there is one undocumented property of this setting class
    preserveTilesOutsideBounds


    This is the property that allow us to update navmesh partially, making a bound and only update what's inside the bound, while, as its name suggest, preserving everything that was already generated outside of the bound

    You need to experiment and understand how it work with bounding box and voxel size. But I have play with it and yes, its work

    ps. The link was a github issue of the https://github.com/Unity-Technologies/NavMeshComponents repo. But that repo was kill the issue system and the unfinished things was all gone

    cc: @TrevorUnity could you please bring back the issue of that github repo. You could freeze it but you should not remove it, there was some info I could found there
     
    acasta, gillemp and vhman like this.
  26. CybeRock

    CybeRock

    Joined:
    Jul 14, 2021
    Posts:
    5
    hey thanks for the detailed reply

    appreciated much
     
  27. berbecarul

    berbecarul

    Joined:
    Apr 7, 2017
    Posts:
    2
    Hello,

    This is the exact setup I am also using, placing obstacles that carve the navmesh around the player for each tree. It does not hitch the game at all. However, I observed that sometimes all agents nearby are stopping for a couple of frames after obstacles are despawned. NavMeshAgent.isPathStale is always false apparently.

    Did you see something like this happening too?
     
  28. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    I have in a city builder game, but I didn't look into it. Maybe it's only if you are calling SetDestinaion every frame.
     
  29. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,163
  30. Tion-Gaming

    Tion-Gaming

    Joined:
    Jan 30, 2015
    Posts:
    28
    https://web.archive.org/web/2020091...nity-Technologies/NavMeshComponents/issues/95

     
    Thaina and vhman like this.
  31. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,163
    Even 2023 preserveTilesOutsideBounds still not being documented
     
  32. THE2FUN

    THE2FUN

    Joined:
    Aug 25, 2015
    Posts:
    63
    Not in runtime, when i want to hit the bake it says that:

    Updating the NavMesh failed due to an excessive number of tiles. Try limiting the distance between surface objects or increasing either the tile size or the voxel size.

    After increasing values, same thing happened.