Search Unity

Need Advice or Recommendations with NavMesh and Agents

Discussion in 'Scripting' started by marjan, Mar 29, 2012.

  1. marjan

    marjan

    Joined:
    Jun 6, 2009
    Posts:
    563
    Hello,
    i am currently diving into the new pathfinding thingies. While i had success with enemies following a character and YES stopping in some distance, i wonder how to setup these things:

    1. Of course you have a user driven character. Mine is currently physics driven. So it does not benefit from the navmesh. I mean, he just can go through any Not walkable area. What is the recommended way to solve this. Just add a navmeshagent to him? Or remove the rigidbody and the physics scripting and control the velocity of the agent? But you still need a collider to catch bullets and so , right? Or use a character controller? If so, why? The Demofiles did not show anything like that.

    2. The Navmesh agent Component seems to be good for Human or animal characters. because of the turning behavior. Everything that turns immediately or on one spot like a Tank can be done somewhat convincingly. But how about a car or a boat? Those can only go forward and cannot spin on a point.

    3. Obstacles. As far as i could figure this out, for an obstacle you simply add Navmesh Agent to the gameobject. But how do you control which object can push away which other object? My results are rather pushypushy. And jittery.
     
  2. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742
    the navmesh works great for static scenes without lots of collidable moving geometry... if your scene changes, you'd have to update the navmesh and re-calculate your paths.

    I made a boat game using this system, the boats use physics, I separated the boat from the agent. I made the agent pathfind, then I made the boat turn towards the agent and accelerate towards it when facing it.
    e.g not facing agent -> boat turns but doesnt accelerate
    facing agent -> boat accelerates.

    Then in turn the agen has a script that 'leads' the boat. If moves faster and slower so that it never leaves the boat behind, based on range from the boat.
    This setup works well.
    ....and boats can pretty much turn on the spot and look ok. (cars can't though)
     
    malkere, Inok and boddole like this.
  3. EddieCam

    EddieCam

    Joined:
    Oct 28, 2009
    Posts:
    26
    For the player character are you not wanting it to go on non-walkable areas? In that case you can just block them off with invisible colliders that only collide with the player layer.

    For obstacles you can put kinematic rigidbodies on to the obstacle agents, but they can still cause funny jitter, stuck characters agents. Or if you know where obstacles are going to be( like for doors/bridges) you can bake those areas on different navmesh layers and toggle them on and off. This gets pretty hard if you have a lot of different layers however.
     
  4. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    1:
    I would definitely base your player controller off a NavMeshAgent and save yourself the time of duplicating the dataset of the NavMesh through colliders.

    Set your rigidbody to kinematic and add a NavMeshAgent to the player GO. Then in stead of modifying the velocity of the rigidbody, modify that of the NavMeshAgent. The most solid way of doing that at the moment is through myAgent.Move (someVelocityVector);

    If you want to handle the player walking into walls a bit more gracefully, use NavMesh.Raycast to shoot a ray forward in NavMesh space and figure out if the player is about to collide with something.

    2:
    You can try modifying the angularSpeed for the agent and see if that yields more desirable results, but if that is not enough control for you, you can always turn off complete NavMeshAgent control and in stead use it to guide a script doing the actual movement.

    So one setup could be to set myAgent.updatePosition = myAgent.updateRotation = false; and then read out myAgent.desiredVelocity for use in a script controlling your car or whatever via a rigidbody or perhaps direct transform modification.

    3:
    One way of adding dynamic obstacles is indeed to attach a NavMeshAgent to them. To avoid the funky behaviour EddieC describes, you'll need to turn off position and rotation updating on them as well.

    There is presently no system for saying "this guy can push that guy, but not the other way around) though. Alternatively - if you just need semi-dynamic obstacles (such as doors), you could use off-mesh links or NavMeshLayers being enabled or disabled.
     
  5. marjan

    marjan

    Joined:
    Jun 6, 2009
    Posts:
    563
    Ahhhh, thanks guys! The first two answers i thought about myself. Good to hear you made something this way and it worked out.

    And another question converning answer 1 to the godfather of unity pathfinding:
    - Why do i need a rigidbody on a character with a Navmeshagent? You say script the velocity of the agent. Whats the rigidbody good for then? Gravity?
    - if there were a rigidbody, what would happen if i use AddForce() to it? I assume nothing, since the NavMeshAgent overrides this, or?
    - Do i need another collider to catch bullets? I mean the navmesh Agent has some kind of a Capsule Collider, but i cannot access it. Thus it seems i need to have an extra one, or not?

    Edit: More Questions
    - if enemys shall constantly follow a character, is it a good idea to set their target every in update? Or because of performace rather do that 1 half a sec or so?
    - are there other ressources on the topic then the older demofiles available under the betas downloadpage?
    - while i was searching for the topic i only found some youtube things where people made a basic follow me. And i found a lot of questions like, my agents don´t stop in a distance, they get pushed away and the like. I think there is the need to have more info on this, be it better documentation or examples or a blog entry or whatever.


    So far i tried to learn from Angry Bots, so my setup of characters is similar to that. Maybe they could modify angry bots to work with Pathfinding instead Physics. That would be interesting to see. Quite a lot of work though.
    Thanks a lot for explaining, AngryAnt.
     
    Last edited: Mar 30, 2012
  6. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    A kinematic rigidbody serves to register a dynamic object with the PhysX runtime without actually receiving feedback from PhysX or affecting the transform of the GameObject it is attached to. You'll need that to have the collider(s) on the character move properly and push other physical objects.

    Remember that moving colliders without rigidbodies assigned (also known as static colliders) will result in the static collision geometry to be recalculated - meaning you end up with a completely unnecessary and massive physics overhead.

    See above - setting a rigidbody to kinematic means it only serves to register and update a dynamic object in PhysX - it doesn't actually affect its transform in any way.

    Just keep the collider you've been using until now. The navmesh agent has no collider - it does not tie into PhysX in any way. What you're seeing is the visualization of the agents size, which is only used in the navigation system.

    The NavMeshAgent doesn't do a complete recalculation of its path if the new destination is close to the old one - in stead it appends to it. However if you have a lot of agents doing that, it will of-course carry a cost.

    I would suggest that you repath in a loop in a coroutine and in there, if myAgent.remainingDistance > kFarAway, yield return new WaitForSeconds (kABitOfTime); else yield return null;

    The example projects from the 3.5 public beta page is what we have at the moment. More are on the way and we're putting these demos on the asset store (meaning they will show up in the gallery section as well) as soon as possible.

    Yea we're shipping more demos soon, but I don't fully understand which problems you're referring to. Could you elaborate?

    Initially we will be shipping new demos showing off how to use the NavMeshAgent for pathfinding as well as player movement, but it is indeed something I have considered. No promises yet though - my TODO list before that eventuality has quite a few items on it ;)


    No problem. Hope you found it useful :)
     
    AndyLaneOlson, sylcc and Guile_R like this.
  7. marjan

    marjan

    Joined:
    Jun 6, 2009
    Posts:
    563
    Thanks a lot again, indeed this information is already very valuable.

    "Yea we're shipping more demos soon, but I don't fully understand which problems you're referring to. Could you elaborate?"

    I can only say what was hard for me to understand, and what i found as questions.

    For me it was not obvious that the acceleration parameter also is invoked in decelaration. Also, Stopping Distance implies that the agent would automatically stop without any further scripting. I found this not the case. Had to do it in script. Also setting the agent to Stop(); and then set its destination again seems to start him again, without having called Resume.
    Figuring this out takes quite some time.

    The other not so abvious things i asked already here and they were answered.
     
  8. kantaki

    kantaki

    Joined:
    May 15, 2011
    Posts:
    254
    i just don't get it,

    i made a cube with :

    navmesh agent rigidbody

    the rigidbody is set to kinematic to register the dynamic object.

    and yes my navmesh agent is trying to avoid the dynamic cube, but if the cube is in the shortest path my navmesh agent just tosses the dynamic cube away.

    is there anyway that i can force a path recalculation ?
     
  9. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Posts:
    3,045
    Sure: NavMeshAgent.ResetPath.
     
  10. kantaki

    kantaki

    Joined:
    May 15, 2011
    Posts:
    254
    ok i think its okay if some dynamic object can be tosses away, but if i spawn a dynamic wall it should behave like a static object.

    can i force a rigidbody/navmesh agent to behave like a static object ? so that the dynamic object wont be moved by physics.
     
  11. yaoklin

    yaoklin

    Joined:
    Jul 16, 2011
    Posts:
    8
    Hello,
    for the dynamic obstacles ,I have some problems.

    for example , in a scene ,I have two dynamic gameobjects A and B, add the Navmesh Agent on both of them .
    I set object A a destination by agent ,but when A is finding the target position ,it will walk through the object B, not bypass it ..

    are there any other operations to control A to bypass B ?

    could you tell me the details ?

    thx in advance !
     
    Last edited: Aug 2, 2012
  12. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    742

    you are taking about collision avoidance, which is a different thing from navmesh following/pathing.
    you have a few options....

    if B isn't moving... set its collision to be a part of the navmesh scene and re-calculate the navmesh temporarily.
    if both A B are moving, then...
    * you could try having sphere collision on both, and let them bump and slide past each other... this may be enough for what you are trying to achieve... but they might also get stuck
    * or You could detect their collision, then add an intermediate destination for both obects... say, back a bit and to the left, then continue on with the original destination
    * you could just let them pass through each other
    * you could look into some fancy "collision avoidance" perhaps there is something on the asset store
     
  13. yaoklin

    yaoklin

    Joined:
    Jul 16, 2011
    Posts:
    8
    Thx for your replies !
    I know what you mean ,but from the above guys said ,there is indeed some way to let the object attached with the NavMeshAgent Component to avoid the dynamic obstacles while it is finding the tartget ..

    for example :



    It seems that if the Object A attached with the NavMeshAgent component want to avoid the Object B(it is moving in the scene) while it is finding the target position.

    just attach a NavMeshAgent to it..

    I also did that ,attach the NavMeshAgent on the Objecet B,but the Object A just walk through the Object B, I got confused ..

    By the way ,If the Object B is static ,I just bake it into the NavMesh, the Object A can bypass it while finding the target.
     
    Last edited: Aug 3, 2012
  14. Eclectus

    Eclectus

    Joined:
    Oct 29, 2012
    Posts:
    4
unityunity