Find closest reachable node with condition

Hi,

I’m trying to use the path system to find the closest reachable save node. For that I’ve created a custom path of which you’ll find some relevant excerpts below. “save” is determined by my own code.

  • It searches like a normal path would only with H value compared to the start position instead of end position
  • It checks every inspected node if it is “save”.
  • If a “save” node is found it marks the path as found and gets the the shortest path to it using the trace function

It always finds the correct save node but the path created by the Trace function is wrong most of the time, it leads to some other position. I guess internally something works different than I expect.

Help greatly appreciated

`
protected void Setup(Vector3 start, Vector3 end, OnPathDelegate callbackDelegate)
{
hasEndPoint = false;
hTarget = (Int3)start;

    callback = callbackDelegate;
    UpdateStartEnd(start, end);
}

public override void CalculateStep(long targetTick)
{

    int counter = 0;

    //Continue to search while there hasn't ocurred an error and the end hasn't been found
    while (CompleteState == PathCompleteState.NotCalculated)
    {

        searchedNodes++;

        
        //Close the current node, if the current node is the target node then the path is finished
        if (currentR.node == endNode)
        {
            CompleteState = PathCompleteState.Complete;
            break;
        }

        if (currentR.H < partialBestTarget.H)
        {
            partialBestTarget = currentR;
        }

        AstarProfiler.StartFastProfile(4);
        //Debug.DrawRay ((Vector3)currentR.node.Position, Vector3.up*2,Color.red);

        //Loop through all walkable neighbours of the node and add them to the open list.
        currentR.node.Open(this, currentR, pathHandler);



        AstarProfiler.EndFastProfile(4);

        //any nodes left to search?
        if (pathHandler.HeapEmpty())
        {
            Error();
            LogError("No open points, whole area searched");
            return;
        }


        //Select the node with the lowest F score and remove it from the open list
        AstarProfiler.StartFastProfile(7);
        currentR = pathHandler.PopNode();
        AstarProfiler.EndFastProfile(7);

        debugPoints.Add((Vector3)currentR.node.position);

        if (IsSave(currentR.node))
        {
            endNode = currentR.node;
            endPoint = (Vector3)currentR.node.position;
            hasEndPoint = true;

           // debugPoints.Clear();
           // debugPoints.Add((Vector3)endNode.position);

            CompleteState = PathCompleteState.Complete;
            break;
        }

        //Check for time every 500 nodes, roughly every 0.5 ms usually
        if (counter > 500)
        {

            //Have we exceded the maxFrameTime, if so we should wait one frame before continuing the search since we don't want the game to lag
            if (System.DateTime.UtcNow.Ticks >= targetTick)
            {
                //Return instead of yield'ing, a separate function handles the yield (CalculatePaths)
                return;
            }
            counter = 0;

            if (searchedNodes > 1000000)
            {
                throw new System.Exception("Probable infinite loop. Over 1,000,000 nodes searched");
            }
        }

        counter++;
    }

protected override void Trace(PathNode from)
{
PathNode otherPN = pathHandler.GetPathNode(endNode);

    base.Trace(otherPN);

}`

Bump

Hi

I would recommend that you take a look at the MultiTargetPath. If you supply a list of points to it, it will find the path to the closest one.

See http://arongranberg.com/astar/docs/class_seeker.php#a811996024eca2a032ad58c847ee2871f
and http://arongranberg.com/astar/docs/class_pathfinding_1_1_multi_target_path.php

I am not quite sure what is wrong with your code though. It looks correct as far as I can see.