Search Unity

NavMeshAgent position best practice?

Discussion in 'Navigation' started by GainfulSage, Jan 8, 2019.

  1. GainfulSage

    GainfulSage

    Joined:
    Apr 30, 2015
    Posts:
    106
    I'm working on a pretty standard seeming challenge - a bunch of AI controlled characters chasing a player on a NavMesh.

    Does it matter how often I [re]set the AI target position? Unity examples (e.g. https://unity3d.com/learn/tutorials/topics/navigation/chasing-until-target-dead?playlist=17105) seem to show updating the target position every frame. Is that reasonable?

    Similarly, I have a working example that uses NavMeshAgent in conjunction with user input to set the destination each frame. It seems to be working fine, but I have seen some references to that being a Bad Idea in some of the other forums.

    Thoughts? Am I setting myself up for later problems?
     
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    When your agents try to follow a moving target like the player, it definitely makes sense to reset the destination every frame, though it can become rather costly indeed if you're dealing with lots of enemies.
    You might want to consider a system where enemies "flock" together as they chase you, where enemies that are nearby form groups and have a single path for that group. You could then also manage these different groups to not have too many simultaneous path generations per frame.

    As for player movement, NavMesh movement makes sense when you're using point-and-click controls, like in Diablo. However, for more direct WASD/Thumbstick controls it indeed doesn't make much sense, and usually feels unresponsive since navmeshAgents use systems like deceleration and turning radius. Besides that, you're making expensive calculations each frame to set the player's path while you could simply have a standard character controller with physics.
     
    GainfulSage likes this.
  3. GainfulSage

    GainfulSage

    Joined:
    Apr 30, 2015
    Posts:
    106
    Thanks for the reply @Yandalf !

    I'm doing a top down game where the deceleration/turning radius effects are exactly what I'm looking for. Recreating that with physics forces would be a huge pain.

    I'm targeting relatively modern machines, not mobile. I'll do some perf tests to see how things hold up on a few different machines and with different numbers of agents. I'll post my findings in a bit...
     
  4. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    GainfulSage likes this.
  5. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Setting the destination each frame is only costly if you have a high number of agents AND
    NavMesh.pathfindingIterationsPerFrame is set to a fairly high number, otherwise this will not showup in your profiler at all.
     
    GainfulSage likes this.
  6. GainfulSage

    GainfulSage

    Joined:
    Apr 30, 2015
    Posts:
    106
    Thanks @DwinTeimlon - that's exactly what I was looking for.

    Also, thanks @Yandalf - right now I have simple ships moving around, and I've got a nice, simple custom code component working nicely. I absolutely am interested in more complex movements, will look at the Locomotion Starter for sure!
     
  7. newjerseyrunner

    newjerseyrunner

    Joined:
    Jul 20, 2017
    Posts:
    966
    I’m making a top down game too, you can see it in the WIP forum (called Mittens.). I alter how often it resets the target dynamically. For just running towards the target, I check it between every half second and quarter second, depending on how far away it is. If it loses any health, it instantly recalculated. When circle strafing it checks every .1 seconds, when meleeing it’s half that. I also have a scalar for both difficulty and type of enemy. Dumb enemies recall about half as often as smarter/faster enemies. In higher difficulties, it scales the time delta down. I find that having a system that allows me to have a variable recall rate both very efficient and allows some interesting behavior.