Search Unity

Can I smooth or curve the NavMesh path?

Discussion in 'Editor & General Support' started by Sherasoft, Dec 10, 2017.

  1. Sherasoft

    Sherasoft

    Joined:
    Nov 17, 2013
    Posts:
    8
    I have a scene with a T-Rex dinosaur chasing a humanoid player so that the T-Rex is the AI NavMeshAgent. Now the animation of the T-Rex is on root motion and I tried all the ways make the turning on the chase look a little bet realistic while respecting the animation but I failed. I have a blend tree contains all the versions of the run animations and turning animations so this is not the issue here. The problem is in the NavMesh path which I was able to observe for debugging after I added a line renderer and a script and specifically the path corners, the issue is hard angel corners makes T-Rex turn in a jerky funny non-realistic way while chasing the player, and however I change the angular speed or speed of him it doesn't matter. I need to control the path to curve it around the corners and I think it's possible because of all the car games around that turn in curvy way. but I don't know how to achieve that because it's not a way-point patrol situation to draw my own path, it's a chase situation where T-Rex will always automatically update the path to chase the player while he runs around away from him. How can I make that possible? the conclusion: I want the T-Rex to make more realistic turning around corners in the navigation path Untitled.png .
     
  2. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    787
    I'd update the path everytime the player moves enough from the last position.
    (So if the real target is 2 or more meters away from the current path-target)

    After all, it doesn't matter if the last point of the path is accurate when it is still many meters away; the path segments in-between won't be affected.

    When the path is calculated, I'd simply smooth it out by splitting each vertex (and repeating that step a number of times).
     
  3. Sherasoft

    Sherasoft

    Joined:
    Nov 17, 2013
    Posts:
    8
    I'm kinda lost here.. I'm not sure that you actually got the point, the issue is not the accuracy of the arrival at destination .. plus this screenshots was taken at the start of the scene while the player still didn't make any move at all, T-Rex spotted him (by the trigger collider) and started the chase and this is the very first path the NavMesh agent has created it. It's the corner in the path what bothering me which I pointed it with red arrow in the image, you see how T-Rex "roughly" changed direction of running animation between the two green arrows? this is the issue. and I think even after continuously changing the destination to create a smoother path like in your method - or if that what you mean with it - sooner or later the player will make hard turns or hide behind obstacle then T-Rex will be forced to hard corner the path again! What I want is to curve the path around the hard corners so T-Rex will smooth turn while running like normal animals movement.
     
  4. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    787
    I know exactly what you mean. :)
    Not sure why the solution is so hard to understand.
    Here is an image that explains it.


    1. Take each vertex (that is your sharp CORNERS).
    2. Split the single vertex into two and separate them along the average-tangent-vector.
    3. repeat step 1 and 2 until the path is smooth enough for you.


    As for the re-calculating the path:
    I just explained that as well because path-smoothing is potentially a cpu-intensive process.

    In other words: Recalculate path only when absolutely needed, path smoothing takes much time.
     
    angrypenguin and Sherasoft like this.
  5. Sherasoft

    Sherasoft

    Joined:
    Nov 17, 2013
    Posts:
    8
    Fantastic! this is exactly what I need but is your approach a performance friendly way? and how to achieve it? the agent scripting is very limited or I'm just too dumb to see the way, Sorry!
     
  6. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    787
    No problem.

    There are a few things to consider here.

    First of all the smoothing operation is expensive, but fortunately there are multiple things we can do to limit the impact as much as possible!

    1) Right now, when your player moves, the trex likely "tracks" the player, right?
    If so, that means it is recalculating the path every frame when the player moves, which is terrible.

    To prevent that, you should manually tell the agent when to calculate a new path.
    Only start calculating a path to the current target when:
    a) the real target position has changed too much
    or
    b) when you're close enough (that means your path only has 2 vertices now, no corners anymore), you just keep calculating every frame and don't do any path smoothing (obviously since you're now only have a start and an endpoint and no points in between anymore).


    2) Limit where you're doing the smoothing
    In the simplest form you can calculate the angle difference at each vertex, and only apply the smoothing operation when the angle is too big (that means when the angle is less than 20° for example, then you wouldn't even attempt to smooth out this vertex).


    3) How to do the smoothing exactly.

    So once you have identified a single vertex that is too "harsh", you first calculate the average-tangent.
    That means:

    // these one you will likely already have since you have to calculate the angle, so the tangents are of course a "side product" that you can reuse for better performance
    var t1 = (currentPoint - previousPoint).normalized;
    var t2 = (nextPoint - currentPoint).normalized;

    // this is the average tangent.
    var avgTangent = Vector3.Lerp(t1, t2, 0.5f).normalized;
    ....

    Here's an image that explains how to do it:



    You should be able to figure it out from here.
    If not, you most likely need to take a few months to learn more about the basics of C# and how to work with vectors. It will be a tremendous help in the long run :)
     
    angrypenguin likes this.
  7. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    12,019
    Nice!

    However...
    ... I wouldn't call the smoothing operation "expensive" in this context. There's only one agent and one path, and we're not talking about a particularly complex path or a large data set. Some of the math operations we're doing along the way are indeed expensive compared to other math operations, but we're just not doing enough of them for it to be a concern here.

    More for the OP: Don't try to optimise something unless you know it is expensive, with a measurable impact on performance. Give this a go with and without path smoothing, and only optimise it if there's a measurable (in the Profiler) and significant difference.
     
    dadude123 likes this.
  8. dadude123

    dadude123

    Joined:
    Feb 26, 2014
    Posts:
    787
    Yes, you are of course correct.

    I had a very specific scenario in mind while I was writing this.

    I worked on a kind of path optimization strategy some time ago that did a lot more than just this.

    Additional chopping, "string pulling", some pretty advanced stuff to even skip path segments when the movement controller allowed it (jumping down arbitrary slopes instead of taking the long way),...

    A path with just 20 or so vertices could sometimes take 100ms+.

    The basic thing I suggested here shouldn't even be noticeable if the path is short.
     
    angrypenguin likes this.
  9. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    12,019
    Yikes..!
     
  10. Ysgramor

    Ysgramor

    Joined:
    Jan 23, 2014
    Posts:
    69
  11. Sherasoft

    Sherasoft

    Joined:
    Nov 17, 2013
    Posts:
    8