Search Unity

How to get a path on the surface of a NavMesh

Discussion in 'Navigation' started by Zenix, Feb 12, 2017.

  1. Zenix

    Zenix

    Joined:
    Nov 9, 2009
    Posts:
    213
    I'm using NavMesh.CalculatePath to get a path and would now like to draw a visualisation of it. The issue is that the calculated path doesn't always follow the surface of the NavMesh, and often dips quite severely below it, so you can't see the visualisation.

    Is there away to ensure the path follows the NavMesh?

    I could of course use raycasts or some other method to find the ground level at each point, but this seems pretty hacky and I'm hoping there's a nicer way.
     
    polous and Mycroft like this.
  2. polous

    polous

    Joined:
    Mar 27, 2018
    Posts:
    4
    Have you found the solution?
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    I'd be curious to see a screen capture of this behavior, or two screen captures: One that shows the NavMesh surface area, and another that shows the visualization of the corners of the path.

    I use a line renderer as a debug visualization of the path my agent will follow. Aside from following off mesh links, I haven't seen the corners of the path deviate from the surface of the navmesh.
     
  4. polous

    polous

    Joined:
    Mar 27, 2018
    Posts:
    4
    The whole problem is that NavMeshAgent.CalculatePath (...) creates an array of waypoints that does not contain all points ... this array does not contain points on inclined surfaces ... (see the figure). In this case, the characters (agents) move as they should - along the path 0 - 1 - 1 '- 2, but the calculated Path contains only points 0 - 1 - 2.
    In the figures: the black curve is Debug.DrawLine for all segments of the calculated Path. As you can see from the figure, there is no dot 1' in the Path.
    How to get intermediate waypoints? This problem does not allow me to draw a path correctly and calculate its length ...
    PS: version of the unit - 2018.1.0f2
     
  5. polous

    polous

    Joined:
    Mar 27, 2018
    Posts:
    4
    Pics
     

    Attached Files:

    • 000.jpg
      000.jpg
      File size:
      583.5 KB
      Views:
      1,344
    • 001.jpg
      001.jpg
      File size:
      309.9 KB
      Views:
      1,194
    • 002.jpg
      002.jpg
      File size:
      471.1 KB
      Views:
      1,270
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,195
    I see what you mean. Good explanation. And I can confirm I get the same behavior as you do, where a direct line between two waypoints can go through the level geometry.

    I haven't thought of any "good" ways to deal with this, but here are a couple of ideas:
    • When drawing the path with the LineRenderer, increase the y-value of each point, so that instead of the line being directly on the NavMesh, it's a meter or so off the ground. This will make it seem like the path it coming out of the character's chest. It won't fix the problem of the line not being parallel to the geometry, but the line might be high enough off the geometry that it doesn't cut into it. Anyway, it's a pretty simple thing to test out to see how it looks.
    • The only thing I can think of if you really need the line to hug the geometry is to break up the NavMesh, and include more Off Mesh Links between areas. In your ramp, for example, on the part where it bends, if you place a collider there which the players don't collide with, but which is excluded from the NavMesh's allowed walkable areas, it will create a hole in the navmesh at that spot. You can "fill" the hole with an off mesh link. But the result will be that your path corners will include two points at that spot, one on each side of the link, instead of going directly from `1` to `2` in your first screenshot. The downsides to this are having to add those invisible obstacles, and having to traverse the offmesh links, which might look silly depending on where you place them.
    Sorry I don't have any better ideas. Good luck, and I'd be interested in hearing whether you come up with a different approach.
     
  7. killakiwi

    killakiwi

    Joined:
    Sep 5, 2013
    Posts:
    22
    Was there any update on this?
     
  8. snfalex

    snfalex

    Joined:
    Jan 9, 2017
    Posts:
    1
    Has anyone figured this out? I'm having this exact same issue...
     
  9. Omer_Behar

    Omer_Behar

    Joined:
    Apr 2, 2021
    Posts:
    1
    I've been looking on and off for an answer to this, finally got one, this thread helped me twice, this is the first time I saw an exact recreation of my problem, thanks polous for the very well written description, the second thing was dgoyette's idea about the height, I took that and implemented a new solution, my line renderer also has only two points, what I did is split that line into X points (15 worked for me but it's really related to the changes of your mesh), and for each point I found the real height of the mesh at that point using a NavMeshQuery:

    Code (CSharp):
    1. NavMeshWorld world = NavMeshWorld.GetDefaultWorld();
    2. NavMeshQuery query = new NavMeshQuery(world, Allocator.Persistent);
    3. NavMeshHit hit;
    4. if (NavMesh.SamplePosition(point, out hit, 10,NavMesh.AllAreas))
    5. {
    6.     point.y = hit.position.y;
    7. }
    8. query.Dispose();
    you can see in the "before" and "after" how the line renderer is fixed and follows the mesh perfectly
    before:
    upload_2023-6-13_17-58-25.png
    after:
    upload_2023-6-13_17-56-33.png