Search Unity

Any way to query 'reachability island' for points on the navmesh? (5.6)

Discussion in 'Navigation' started by BenHymers, Apr 12, 2017.

  1. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    I just want to do a very quick check for whether a given point is reachable from another, by hopefully comparing something like a 'reachability island ID', where all polys that are reachable from each other share an ID. I know other pathfinding libraries support this.

    Is such a thing generated and stored anywhere in the Unity 5.6 navmesh?
     
    idbrii likes this.
  2. Cleverlie

    Cleverlie

    Joined:
    Dec 23, 2013
    Posts:
    219
    I second this, I'm doing sort of a tower defense game and I need to check if all spawn points for enemy units are able to reach the end/target point each time I put a new tower on the map, so towers cannot completely block enemy paths to their final target, I'm using the old unity's navmesh obstacle to carve the navmesh on runtime.

    if only I could ask if after adding a tower (obstacle) and therefore carving the mesh, the mesh is now divided in more sections than before, then I can ask if the section/region/connected polygons that contains the end point and the start point are the same, asking for a path with CalculatePath(spawnPoint, TargetPoint); is not an option because I also need to check if I'm not isolating any of the current enemies in an island:

    RED POINT = target/end
    GREEN POINT = start/spawn point
    CYAN POINTS = enemy units
    YELLOW BLOCKS = towers/navmeshObstacles

    navmesh problem.jpg

    doing a CalculatePath() for each enemy would be expensive (100+ enemies in the map), so I could just take all islands and do something like this (pseudo code):

    Code (CSharp):
    1. bool IsTowerCreationForbidden()
    2. {
    3.    bool forbidTowerCreation = false;
    4.    foreach (Island in Navmesh.Islands)
    5.    {
    6.        if (island.containsAgent())
    7.        {
    8.            bool pathFound = island.GetAnyAgentInThisIsland().CalculatePath(start,end);
    9.            if (!pathFound)
    10.            {
    11.                forbidTowerCreation = true;
    12.                break;
    13.            }
    14.        }
    15.    }
    16.     return forbidTowerCreation;
    17. }
     
  3. Jakob_Unity

    Jakob_Unity

    Joined:
    Dec 25, 2011
    Posts:
    269
    Not there's no inherent "island ID" in the navmesh system. If you know the island locations in advance you can calculate paths and check if the resulting path status is : `NavMeshPathStatus.PathComplete` - meaning the two ends are connected . Notice that the path calculated will be using any links if possible, this may or may not be desired.
     
  4. BenHymers

    BenHymers

    Joined:
    Dec 16, 2014
    Posts:
    30
    That's a shame! It would be fairly easy to add.

    Ok, if I want to do this myself, is there any data I can use about poly connectivity, so I can extract connected components easily? The most likely candidate looks like NavMesh.CalculateTriangulation - but do you know if verts are guaranteed to be unique, so polys sharing two indices are connected? IIRC that's the case in Recast/Detour but I don't know how far you guys have diverged.

    It would seem very messy to have to guess at poly connectivity by comparing poly vert positions. If connectivity information isn't exposed anywhere, can I request it please?

    Edit: I can get some of the way with requesting paths between some region centres for now thanks, but this isn't going to scale at all well!
     
    lclemens and idbrii like this.
  5. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    Yeah, it really is a shame. A* Pathfinding Project assigns unique numbers to islands and in fact it has a function called IsPathPossible() that simply verifies if the island numbers are the same and the two points have a walkable status.