Only travel through forward-direction nodes in the graph

  • A* version: [5.4.6]
  • Unity version: [6.5]

I am using the A* Pathfinding Project in a Point Graph setup.

I want aircraft to never move backwards — they should only travel through forward-direction nodes in the graph.

However, A* is currently finding the shortest path, which can include U-turns, causing the aircraft to turn around and move in the opposite direction.

Also, this restriction should apply only to the specific agent (aircraft) that is currently calculating the path, not globally to all agents or the entire graph.

How can I restrict this behavior within a Point Graph setup?
Is there a way to enforce directional (forward-only) traversal using traversal providers, custom costs, or graph design, or is Point Graph not suitable for this kind of directional movement constraint?

Check out using Connect. The last argument takes an OffMeshLinks.Directionality argument. Left is using the code underneath and right is just using a normal point graph.

void Start(){
    PointNode[] nodes = AstarPath.active.data.pointGraph.nodes;

    for (int i = 0; i < nodes.Length; i++) {
        nodes[i].ClearConnections(true);
    }

    for (int i = 0; i < nodes.Length; i++) {
        if (i < nodes.Length - 1){
            PointNode.Connect(nodes[i], nodes[i + 1], 0, OffMeshLinks.Directionality.OneWay);
        }
        
        if (i == nodes.Length - 1){
            PointNode.Connect(nodes[i], nodes[0], 0, OffMeshLinks.Directionality.OneWay);
        }
    }
}

Thank you!

However, in my case the graph needs to remain bidirectional because aircraft may approach the same taxiway from opposite directions. I only want to prevent an aircraft from making an immediate 180° U-turn during pathfinding, while still allowing another aircraft to use the same connection in the opposite direction.

Would ITraversalProvider be the recommended solution for this, or is there another approach?

I made the connections this way

PointNode[] nodes = AstarPath.active.data.pointGraph.nodes;

       
WayPoint[] waypoints = FindObjectsByType<WayPoint>(); 


foreach (WayPoint waypoint in waypoints)
{

    waypoint.pointNode = AstarPath.active.GetNearest(waypoint.transform.position).node as PointNode;
    
}


foreach (PointNode node in nodes)
{
    node.ClearConnections(true);
}


foreach (WayPoint waypoint in waypoints)
{
    if (waypoint.pointNode == null)
        continue;

    foreach (Transform targetTransform in waypoint.connectedPoints)
    {
        if (targetTransform == null)
            continue;

        WayPoint targetWaypoint = targetTransform.GetComponent<WayPoint>();

        if (targetWaypoint == null || targetWaypoint.pointNode == null)
            continue;

        PointNode.Connect(
            waypoint.pointNode,
            targetWaypoint.pointNode,
            0,
            OffMeshLinks.Directionality.TwoWay
        );
    }
}
public class WayPoint : MonoBehaviour
{
    public List<Transform> connectedPoints;


    [System.NonSerialized]
    public PointNode pointNode;
}

Yeah this is likely where I’d go next with it as well. Maybe do a Vector3.Dot between the current rotation and the direction to the node in CanTraverse().

Thanks! That solved it. I only applied the direction check on the first node connection, and now the aircraft takes the longer forward path instead of making a 180° turn. Thanks for your help!

1 Like

Glad to help!

1 Like