Search Unity

Navmesh layers

Discussion in 'Developer Preview Archive' started by PeterB, Dec 23, 2011.

  1. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    The navmesh functionality in the preview of Unity 3.5 Pro works great, and the NavMeshAgents are very simple to use for the majority of use cases. Good job. I'm really looking forward to the release.

    However, how do I generate navmeshes for different navmesh layers? It's clear from the documentation how they work, but how do I, for instance, with normal terrain, make underwater regions unpassable to certain NavMeshAgents? The NavMeshLayer editor allows me to define the cost for existing and new layers — but how do I define the data used by those layers?
     
    EsoEs likes this.
  2. Pixelstudio_nl

    Pixelstudio_nl

    Joined:
    Jun 22, 2009
    Posts:
    179
    you mean setting layer masks for agents ?
     
  3. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    No, not at all. That part is a no-brainer, as is how different meshes can be put in different layers when the navmesh, which of course always is global, is baked.

    What I'm trying to achieve is specific to Terrain objects, or to any large mesh object where parts of the same object should go to different layers in the navmesh. For instance, to be specific: underwater navmesh geometry properly belongs to a different layer than the normal walkable parts, otherwise there is no way of generating a navpath for NavMeshAgent which avoids going through water (which might result in some of your NPCs drowning).

    Another very common situation is where parts of the terrain have a higher traversal cost than others. For instance, parts of your terrain might be swamp and thus should be weighted higher.

    Yet another case would be for parts of the traversable navmesh to be put in different layers depending on the slope angle at a given terrain point, which is used to make NPCs prefer even ground.

    The only workaround I can think of for the suppression of underwater paths is to put a *huge* NavMeshAgent on the Water object, to block passage. This would effectively be the same as not generating the underwater parts of the navmesh at all (which would be even better, unless the underwater navmesh is needed for bottom-dwelling NavMeshAgents). I'm not sure if such an extreme measure is best practice in this case, though. Automatic assignment of navmesh geometry to layers depending on height would solve this particular problem quite nicely.

    The third case, that of slope angle based layer distribution, doesn't seem to be achievable at all in 3.5, unless there are parts of the API which haven't been made public.
     
    Last edited: Dec 23, 2011
    EsoEs likes this.
  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Project Settings -> NavMesh layers you can create named navmesh layers.

    In the "nav mesh window" object tab you can pick the navmesh layer of the renderer. When it is baked this data is transformed into the navmesh. At runtime you can change the navmesh layer costs and also forbid agents to walk on some layers alltogether.

    You can tweak layer cost on a global basis and also override it on a per agent basis.
     
  5. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    Thanks, Joachim, but again, my question is not about how to create named layers, but about how to split data in the global navmesh into separate layers, either during baking or afterwards. Am I being unclear or am I misunderstanding something? I just expanded the previous post to be a little more specific.
     
    IgorAherne likes this.
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    In the "nav mesh window" object tab you can pick the navmesh layer of the renderer. This tags the renderer to be of a specific layer.
    When baking Unity will generate the navmesh polygons based on what you have setup in the renderers.

    It will color different layers differently in the navmesh visualization.


    If you have a single huge mesh, then you should either split the mesh so you can put it in different layers. Or you just add another mesh or cube on top that is not rendered in the game, but simply tags the surface with the layer you want.
     
    Last edited: Dec 23, 2011
  7. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    Thanks Joachim, but we're talking about different things.

    Maybe I didn't stress enough that this has to do with Terrain meshes specifically. Did you read my second entry in this thread? Let me rephrase it and simplify the basic question as much as I can.

    1) There is a Terrain.
    2) There is a Water object at a certain Y level, dividing the terrain into dry ground on one hand, and sea on the other.
    3) There's an NPC which should only move on land.

    How do you bake the navmesh so that the NPC avoids the water?
    How do you bake the navmesh so that another kind of NPC stays only in the water?

    The other questions I had derive from this scenario. In other words: how do I delegate different parts of one and the same Terrain object to different navmesh layers? Is it possible? If not, what workarounds do you propose, as this is a very, very common scenario?
     
    Last edited: Dec 23, 2011
    IgorAherne likes this.
  8. Democre

    Democre

    Joined:
    Mar 31, 2010
    Posts:
    345
    is the walkableMask property of NavMeshAgent what you are looking for?

    I don't believe there is a way to automatically split navmeshes based on a height though. So you would have to create different navmesh layers manually.
     
  9. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    The walkable Mask property would be used to control what layers are used when calculating a path from the navmesh layers, yes.

    If layers can't be derived from properties of the terrain (such as height or slope), and if there's no way of modifying the navmesh layer content after it has been baked, then pathfinding in 3.5 really only is of very limited use, namely for smaller projects with fairly simple geometry. It would be very strange, and out of character, if the folks at Unity have designed pathfinding without the necessary flexibility to support the requirements of terrains. Especially if it's a Pro only feature.
     
  10. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    You cannot bake a single terrain (or any mesh) into two different layers.

    A workaround could be to apply an approximate mesh onto the terrain - where you're masking out the water region.
    - that layer should be Navigation Static and have the appropriate NavMeshlayer - after baking you should disable the object altogether.

    Same method can be used for roads in terrain - where the masking mesh is approximating the roads.

    Cheers..
    /Jakob
     
  11. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    Thanks, Jacob, I thought as much. I hoped there was a faster way of doing it, since wrapping an approximate mesh to a very large terrain is a tremendous amount of work. But I guess in the case of water surfaces, a horizontal plane might work too. Many road tools generate path meshes, which can be used for the other cases. Will the data format of the navmesh be documented? If so, postprocessing tools could be added by the community.
     
  12. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    yeah - i was wondering about that water ;-) - i thought you wanted the seabed - and the possibly offset the agent vertically. But when thinking more about it - it makes more sense to bake the water surface, then allowing swimming agents to be offset between water surface and seabed (by getting the terrain height) - when diving.

    I forgot to mention - that supporting flying agents can be done similarly (and have so in e.g. Shadowgun) - by adding an "invisible" plane above the ground.

    Exposing the data - and how to do it - is something we have yet to decide on.

    Cheers..
    /Jakob

     
  13. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    366
    Pathfinding on the seabed would only be useful for, say, crawlies such as crustaceans, otherwise water movement is just like flying, which requires a different take on navigation: the navmesh is useful as an adjunct, as it would look strange if a flying object followed the same path as gravity-bound agents. One way is to look ahead along the calculated path and go straight to any unobstructed farther point on the X-Z plane.

    Another scenario where an underwater navmesh is useful is for those cases when a non-swimming NPC should only elect to go through water if no other route is at all possible, as a kind of last resort. But I was making a point on the flexibility needed for generating large terrain-based navmeshes in general.

    Another way of doing this would be to create two copies of the terrain. In one of the copies all terrain below water level would have its height set to 0. In the other, all terrain above water level would have its height set to the maximum terrain height. These two would be assigned to different layers, the original terrain would be ignored for baking, and afterwards the copies would be deleted or disabled, and the original terrain brought back in. This would give you two height-based, complementary layers which can be used as one wishes. The technique could be extended to more layers if necessary.

    It would be great if there were an API to the layer aspect of the navmeshes. Being able to assign parts of the navmesh to different layers - post baking - depending on their slope, for instance, would be very useful. Should I post a feature request somewhere, or can I just leave the suggestion with you? :)
     
    Last edited: Dec 26, 2011