Navmesh How to check if full path available? C#

I want to have a build mode where you can place buildings on a grid. Then you can press a Ready button to spawn enemy units that will use navmesh to find their way to a target position. But I don’t want players to be able to leave the build mode if there is no path available to the target position. So I want to calculate a path from spawn position to target position and if it is available, store the path, and flag a bool.

Outside of build mode, I want all units to use the same path that was already calculated. What I have so far almost does this. Using the CalculatePath() function however, returns true if just part of the path is available. I want it to only return true if a complete path is available. Otherwise you can leave build mode and the units end up only going part of the way.

As you can see, the enemy unit (Green capsule) finds the shortest path to the target position (Blue cube) and stops part way because there is no path from there to the target position. I dont want this. I want the path bool to only be true if the complete path is available, not just part of the path.

Here is the manager script I’m using to calculate the path.

using UnityEngine;
using System.Collections;
  
public class EnemyUnitManager : MonoBehaviour {  
    public NavMeshAgent spawnPosition;
    Transform targetPosition;
  
    [HideInInspector]
    public bool pathAvailable;
    public NavMeshPath navMeshPath;
  
    void Start() {
        navMeshPath = new NavMeshPath();
        targetPosition = GameObject.FindGameObjectWithTag("Target").transform;
    }
  
    void Update() {
        pathAvailable = spawnPosition.CalculatePath(targetPosition.position, navMeshPath);
    }
}

And this is the script for the enemy unit.

using UnityEngine;
using System.Collections;
  
[RequireComponent (typeof(NavMeshAgent))]
public class Enemy : MonoBehaviour {
  
    public EnemyUnitManager unitManager;
  
    NavMeshAgent unit;
  
	void Start () {
        unit = transform.GetComponent<NavMeshAgent>();
	}
  
	void Update () {
        if (Input.GetButtonDown("Jump")) {
            if (unitManager.pathAvailable == false) {
                Debug.Log("Path not available");
            }
            else {
                unit.SetPath(unitManager.GetComponent<EnemyUnitManager>().navMeshPath);
            }
        }
	}
}

Solved It. I’ll post it here for anyone else with the same problem.

Instead of using the bool returned on the CalculatePath() function, you can check the path.status after you have calculated the path.

if (path.status != NavMeshPathStatus.PathComplete) {}.

For anyone interested this is what I did for my code.

using UnityEngine;
using System.Collections;
  
public class EnemyUnitManager : MonoBehaviour {
  
    public NavMeshAgent spawnPosition;
    Transform targetPosition;
  
    [HideInInspector]
    public bool pathAvailable;
    public NavMeshPath navMeshPath;
  
    void Start() {
        navMeshPath = new NavMeshPath();
        targetPosition = GameObject.FindGameObjectWithTag("Target").transform;
    }
  
    void Update() {
        if (/*UI Button Press*/) {
            if (CalculateNewPath() == true) {
                pathAvailable = true;
                print("Path available");
            }
            else {
                pathAvailable = false;
                print("Path not available");
            }
        }
    }
  
    bool CalculateNewPath() {
        spawnPosition.CalculatePath(targetPosition.position, navMeshPath);
        print("New path calculated");
        if (navMeshPath.status != NavMeshPathStatus.PathComplete) {
            return false;
        }
        else {
            return true;
        }
    }
}

As to keep the computational cost down I am calculating the path only when a button is pressed and then checking if the path reaches the target position. I only continue if this is true. I then assign the already calculated path to each enemy unit when they spawn. So they are only updating movement and not calculating their own path.

This works fine for my purposes, but if you would like to update the path while units are spawning, you can call the CalculateNewPath() function more often or put it in Update() and that path will be assigned to all your units. Or you can have each unit calculate their own path with SetDestination()

2 years later…thanks!

2019 and this answer still helped me, thanks a lot!

Here we are in 2020 hahaha, Thanks buddy !

2022 and this is still helpful :smiley: Thanks man :smiley:

Thanks A LOT !!!

lot of thx from 2023