How to throw out unwalkable targets from MultiTargetFree?

Hello :slight_smile:

I have adjusted the MultiTargetFree slightly to automatically find targets based on tag which works.

Now the problem is that only 1 of 2 targets is reachable. Fine, but how can I throw out the ones that are unreachable? Now I get the error message that “One target could not be reached”, but it doesn’t want to walk to the reachable target. If the PRO version solves this automatically, I’m more than happy to consider buying it.

I tried putting PathUtilities.IsPathPossible in here, but it doesn’t solve the problem for the reason that there is an actual possible path to another target, so the statement is true. I think.

A* settings I put on max nearest node to 1 instead of 100. Otherwise it would walk towards the unreachable target anyway, as it would be within the amount of nodes.

Kind regards,

T

Here is my current script:

public List<Transform> targets;
private Path[] lastPaths;
private int numCompleted = 0;
private Path bestPath = null;
int walking = 0;
IAstarAI ai;
int index;

        void Start()
        {
 targets = new List<Transform>();

            GameObject[] watersilo = GameObject.FindGameObjectsWithTag("test");
            foreach(GameObject test in watersilo)
            {
                targets.Add(test.transform);
            }

            SearchClosest();
        }



        protected override void Awake()
        {
            base.Awake();
            ai = GetComponent<IAstarAI>();
        }

        public void SearchClosest()
        {
            //If any paths are currently being calculated, cancel them to avoid wasting processing power
            if (lastPaths != null)
                for (int i = 0; i < lastPaths.Length; i++)
                    lastPaths[i].Error();
            //Create a new lastPaths array if necessary (can reuse the old one?)
            if (lastPaths == null || lastPaths.Length != targets.Count) lastPaths = new Path[targets.Count];
            //Reset variables
            bestPath = null;
            numCompleted = 0;
            //Loop through the targets
            for (int i = 0; i < targets.Count; i++)
            {
                ABPath p = ABPath.Construct(transform.position, targets[i].transform.position, OnTestPathComplete);

                lastPaths[i] = p;


                    AstarPath.StartPath(p);

            }
        }
        

        public void OnTestPathComplete(Path p)
        {
            if (p.error)
            {
                Debug.LogWarning("One target could not be reached!\n" + p.errorLog);
            }
            //Make sure this path is not an old one
            for (int i = 0; i < lastPaths.Length; i++)
            {
                if (lastPaths[i] == p)
                {
                    numCompleted++;
                    if (numCompleted >= lastPaths.Length)
                    {
                        CompleteSearchClosest();
                    }
                    return;
                }
            }
            
        }




        public void CompleteSearchClosest()
        {
            //Find the shortest path
            Path shortest = null;
            float shortestLength = float.PositiveInfinity;
            //Loop through the paths
            for (int i = 0; i < lastPaths.Length; i++)
            {
                //Get the total length of the path, will return infinity if the path had an error
                float length = lastPaths[i].GetTotalLength();
                if (shortest == null || length < shortestLength)
                {
                    shortest = lastPaths[i];
                    shortestLength = length;
                }
            }
            Debug.Log("Found a path which was " + shortestLength + " long");
            bestPath = shortest;
            
        }


        public void Update()
        {
            if (bestPath != null && bestPath.vectorPath != null && walking == 0)
            {
                ai.SetPath(bestPath);
                walking = 1;
            }
                //Highlight the best path in the editor when it is found
                if (bestPath != null && bestPath.vectorPath != null)
            {
                for (int i = 0; i < bestPath.vectorPath.Count - 1; i++)
                {
                    Debug.DrawLine(bestPath.vectorPath[i], bestPath.vectorPath[i + 1], Color.green);
                    
                }




            }
        }
    }
}```

I think I managed to solve it. The unreachable path returns a length of 0, so what I did was:

if (shortest == null && length > 0 || length < shortestLength && **length > 0)**
                {
                    shortest = lastPaths[i];
                    shortestLength = length;
                }

That should only take into account paths more than 0 length!

If I bump into a problem with this, I’ll let you know

1 Like