Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Multiple NavmeshSurface calculate path.

Discussion in 'Navigation' started by larnin, Sep 18, 2017.

  1. larnin

    larnin

    Joined:
    Sep 18, 2017
    Posts:
    1
    Hi,

    I use this new navmesh system for my game :
    https://github.com/Unity-Technologies/NavMeshComponents
    i'm still in unity 5.6 and can't upgrade now to 2017 versions (in case if a possible easier or better solution exist in newer version).

    In my game i have 4 navmesh surface, one for each type of agents who don't share the same size, areas and area costs.

    I want to calculate a possible path for a specific type of agent, but without an agent available (i can't use the CalculatePath function from NavmeshAgent).
    Instead, i use the Static function CalculatPath from Navmesh, but it don't use the right navmesh surface.
    For exemple here, the green line is the calculated path, but my agent can't use stairs.
    Capture d’écran 2017-09-18 à 16.41.31.png

    Is there a way to use the wanted NavmeshSurface to calculate a path without having an agent ?

    Thanks you for your answer.

    ps : sorry for my bad english, it's not my native language.
     
  2. adriant

    adriant

    Unity Technologies

    Joined:
    Nov 1, 2016
    Posts:
    68
    Hi,
    Have you had any success in overcoming this issue since you posted the question here?

    The solution is to use this overload (variant) of the NavMesh.CalculatePath() function, which allows the precise agent type to be specified when doing the query:
    Code (CSharp):
    1. public static bool CalculatePath(Vector3 sourcePosition, Vector3 targetPosition, AI.NavMeshQueryFilter filter, AI.NavMeshPath path);
    This will restrict the pathfinding to only one type of surface.

    The NavMeshQueryFilter parameter that is passed into the function has an agentTypeId member which specifies the agent type by which the NavMesh surface is identified (the one that was used when the surface was baked).

    Please see this thread as a hint for how to obtain an agentTypeId https://forum.unity.com/threads/how-do-i-get-the-int-value-of-a-navigation-agent-type.472340/ .

    Pay attention please to the fact that NavMeshQueryFilter also applies modified area costs to the path search. By default all costs will be set to 1 in a newly created filter. You can use NavMesh.GetAreaCost() to obtain the actual costs that you had already prepared in the navigation settings and then write them into the filter using the its SetAreaCost() method. Of course you can freely change the costs if it makes sense for your use case.

    Regarding the buggy behaviour you have noticed, the variant of NavMesh.CalculatePath() function that does not take a NavMeshQueryFilter as a parameter currently has an issue when multiple NavMesh surfaces overlap near the start or end point.
     
    vhman, OldKing_Wang and Claytonious like this.
  3. PabloNoBrakesGames

    PabloNoBrakesGames

    Joined:
    Mar 19, 2019
    Posts:
    4
    Hi,
    I followed what your notes but it doesn't work for me. The path is always empty, path.corners with length zero (I know it takes a few frames to calculate). I get the proper agentTypeID accessing to it from the NavMeshSurface, (I also checked debugging that is the proper id).

    Code (CSharp):
    1.  
    2. [SerializeField] private NavMeshSurface navMeshSurface;
    3. private NavMeshQueryFilter navMeshQueryFilter;
    4. private NavMeshPath path;
    5.  
    6. private void Awake()
    7. {
    8.      path = new NavMeshPath();
    9.      navMeshQueryFilter = new NavMeshQueryFilter();
    10.      navMeshQueryFilter.agentTypeID = navMeshSurface.agentTypeID;
    11.      navMeshQueryFilter.areaMask = navMeshSurface.defaultArea;
    12. }
    13.  
    14. void Update()
    15. {
    16.      NavMesh.CalculatePath(transform.position, targetPosition, navMeshQueryFilter , path);
    17. }
    18.  
    This path returns always empty, but if I instead try to get the path through all areas like this it works properly
    Code (CSharp):
    1.  
    2. void Update()
    3. {
    4.      NavMesh.CalculatePath(transform.position, targetPosition, NavMesh.AllAreas, path);
    5. }
    6.  
    Any ideas of how I can get this working? I need to use the CalculatePath method with different NavMeshSurfaces, so I can calculate paths depending on the agents, and this seems to be the only way to go.

    Any help will be appreciated :)

    PS: I think the navMeshQueryFilter can only filter AREAS, but has nothing to do with surfaces.
     
    Last edited: Aug 28, 2019
  4. PabloNoBrakesGames

    PabloNoBrakesGames

    Joined:
    Mar 19, 2019
    Posts:
    4
    Okk, got it working, I was specifying badly the mask:

    Code (CSharp):
    1. navMeshQueryFilter.areaMask = navMeshSurface.layerMask;
    Hope this helps someone else :)
     
  5. SpaceManDan

    SpaceManDan

    Joined:
    Aug 3, 2013
    Posts:
    15
    If anyone is still paying attention to this I need help!


    I'm having an issue with calculating paths. First off, yes my public fields have the correct variables assigned in the inspector.

    If I bake my nav mesh from within the NavMeshSurface component that has been applied to my gameObject, the navmesh generates just fine using the agentID I intend. You can see the blue area applied nicely exactly how it is supposed to. If I run the code below, the path.corners.length will be 0 (No path).

    NOW, if I open unity Navigation menu, click on the Bake tab, and bake the same agentID I used before, I will also see a second newly generated navigation mesh nicely laid out over my scene. Now, if I do not change a thing about my code and run the scene, the path.corners.length will now be filled with waypoints as expect. The problem with this is it negates the point of using NavMeshSurfaces all together. The point of which being that I can bake multiple agentID's for use in my scene. If I can not calculate paths on NavMeshSurfaces I'm afraid it's pointless to use surfaces.

    My fear is that NavMesh.CalculatePath(); does not work with navMeshSurfaces. Can anyone confirm? Or tell me what it is I'm doing wrong?

    Code (CSharp):
    1. public Transform target;
    2.         public NavMeshPath path;
    3.         public NavMeshSurface navMeshSurface;
    4.         private NavMeshQueryFilter navMeshQueryFilter = new NavMeshQueryFilter();
    5.  
    6.         private float elapsed = 0.0f;
    7.  
    8.         void Start()
    9.         {
    10.             path = new NavMeshPath();
    11.             elapsed = 0.0f;
    12.  
    13.             navMeshQueryFilter.agentTypeID = navMeshSurface.agentTypeID;
    14.             navMeshQueryFilter.areaMask = navMeshSurface.layerMask;
    15.         }
    16.  
    17.         void Update()
    18.         {
    19.             elapsed += Time.deltaTime;
    20.             if (elapsed > 1.0f)
    21.             {
    22.                 elapsed -= 1.0f;
    23.                 NavMesh.CalculatePath(transform.position, target.position, navMeshQueryFilter, path);
    24.             }
    25.             for (int i = 0; i < path.corners.Length - 1; i++)
    26.                 Debug.DrawLine(path.corners, path.corners[i + 1], Color.red);
    27.  
    28.  
    29.         }
     
  6. SpaceManDan

    SpaceManDan

    Joined:
    Aug 3, 2013
    Posts:
    15
    I have run multiple tests and can confirm, NavMesh.CalculatePath() and NavMeshAgent.CalculatePath() will only work with the first agentID and will only work if you use the legacy (Default) navigation bake. Basically, no point in using surfaces if you intend use navmeshes to calculate your own paths. Currently you MUST use the NavMeshAgent.SetDestination() if you want to work with multiple surfaces.

    TL;DR You can only use the default navMesh, not surfaces if you want to calculate your own path and not use the NavMeshAgent.
     
  7. Claytonious

    Claytonious

    Joined:
    Feb 16, 2009
    Posts:
    900
    This is working correctly here with multiple agent types. I am not seeing this problem. Maybe something in our setups is different. I am on Unity 2019.2.9.

    My surfaces look like this, so you can contrast with yours:
     
  8. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    It's working just fine for me, so maybe your setup is broken.
     
  9. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    350
    I'm also have same issue. With some variations: NavMesh.CalculatePath() does not work as expected, but NavMeshAgent.CalculatePath() works with multiple agents.

    Can somebody share working copy of project?
     
  10. SpaceManDan

    SpaceManDan

    Joined:
    Aug 3, 2013
    Posts:
    15
    Please do share more than just saying my stuff is broken. It's not very helpful.

    If you really want to help, show me what you got and explain, seeing as thats why were all here.
     
  11. SpaceManDan

    SpaceManDan

    Joined:
    Aug 3, 2013
    Posts:
    15
    Hey, I just saw this reply you sent. I'll check it out and get back to you. Appreciate the screenshot!
     
  12. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Calm down really. You are stating its not working for all us which is simply not true. I wanted to make clear to other people, that it is actually working, as you obviously didn't answer to that thread for a month.

    If you need help you have to provide more information. Show a screenshot of your navmesh + settings. Also what what is your exact layermask, agent setting etc. Your piece of code does not give me any clues.
     
    Last edited: Nov 13, 2019
  13. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    350
    I does work, it doesn't, it does work, it doesn't.

    I know that there is no sense to prove anything. But share base project with two meshes and NavMesh.CalculatePath().
    I will integrate it into demo so everybody can use it: https://github.com/h8man/RedHotSweetPepper
     
  14. vhman

    vhman

    Joined:
    Aug 13, 2018
    Posts:
    350
    If anyone have issues read second post from top to bottom! Multiple agent and surfaces are working fine.
    I totally missed area cost setting
    Code (CSharp):
    1.         var navMeshQueryFilter = new NavMeshQueryFilter()
    2.         {
    3.             agentTypeID = Agent.agentTypeID,
    4.             areaMask = Agent.areaMask,
    5.         };
    6.         for (int i = 0; i < 32; i++)
    7.         {
    8.             navMeshQueryFilter.SetAreaCost(i, Agent.GetAreaCost(i));
    9.         }
     
  15. altet777

    altet777

    Joined:
    Apr 6, 2019
    Posts:
    1
    I was suffering from the same problem, but now I can use it by changing the y coordinate that is given.

    Vector3 srcpos = myObj.transform.position;
    Vector3 trgpos = moveTrgPos;
    srcpos.y =
    trgpos.y = 20.0f; // from NavMeshAgent Obj y-pos
    bool res = NavMesh.CalculatePath(srcpos, trgpos, NavMesh.AllAreas, naviPath);