ABPath not taking into account GraphUpdateScene. Could I put the destination of ABPath as a target instead of creating a path then?

Hello! :slight_smile:

I have worked with the MultiTargetFree example. Basically what it does now is that it calculates the paths,and the shortest is set “SetPath(bestPath);”
Now the problem is that the ABPath calculation doesn’t seem to take GraphUpdateScene into account. I tested this by changing the MultiTargetFree to the AIDestinationSetter.

The best thing that I would like, is that the destination of bestPath will be used as a target like in AIDestinationSetter rather than SetPath. And then in Update write it like AIDestinationSetter (if (target != null && ai != null) ai.destination = target.position;)
That means that target = endofpath or that the return of the script is the object with the closest path instead of the actual path :sunny:

A second solution I can think of, if is there is some way to use GraphUpdateScene into ABPath.

The code:

        public List<Transform> targets;

        private Path[] lastPaths;

        private int numCompleted = 0;

        private Path bestPath = null;

        int walking = 0;
        IAstarAI ai;
        int index;
        private float length;
        int pathspecific = 0;

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

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

            StartCoroutine(waitForScan());
        }


        IEnumerator waitForScan()
        {
            yield return new WaitForSeconds(1);
            SearchClosest();
        }


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


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

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

            //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 > 0.1 && length < 10 || length < shortestLength && length > 0.1 && length < 10)
                {
                    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);

                }
            }

So at the moment I seem to have solved it like this:

        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 > 0.1 && length < 10 || length < shortestLength && length > 0.1 && length < 10)
                {
                    shortest = lastPaths[i];
                    shortestLength = length;
                }
            }
            bestPath = shortest;
            walking = 0;

            int number = bestPath.vectorPath.Count;
            if (bestPath != null && bestPath.vectorPath != null) endofdestination = new Vector2(bestPath.vectorPath[number - 1].x, bestPath.vectorPath[number - 1].y);
            Debug.Log(endofdestination);
            ai.destination = endofdestination;
        }

        public void Update()
        {

            if (target != null && bestPath != null && bestPath.vectorPath != null && walking == 0)
            {
                //ai.SetPath(bestPath);
                walking = 1;
                int number = bestPath.vectorPath.Count;
                Debug.Log(endofdestination);
            }

            if (target != null && ai != null) ai.destination = endofdestination;

I’m impressed by myself XD

Ok so actually this did not solve it. It does set the target to the objective (green) which is good, but unfortunately it still calculates the closest Path, including unreachable targets!

I think I solved it :open_mouth: I’ll let you know if I see any problems with my current solution

1 Like