How to setup FleePath with FollowerEntity w/DestinationSetter?

  • A* version: 5.3.8
  • Unity version: 2022.3.41

Hi there,

I am attempting to get a FleePath working for my NPCs and have the current code below.

fleePath = FleePath.Construct(npc.transform.position, npc.witnessedCrime.transform.position, 10000);

fleePath.aimStrength = 1;
fleePath.spread = 4000;

npc.SetCustomTarget(fleePath.endPoint);

The SetCustomTarget function just sets the position of an empty transform that is always assigned in the AIDestinationSetter component.

The example on the docs using the seeker component has a callback for path complete when doing SetPath(), but the FollowerEntity version doesn’t, so I don’t think I can use it this way.

Looking at the docs it seems the Path may not be calculated immediately, so I tried doing a similar thing in the callback (which looks to be when the path has finished calculating), but that only passes the Path class, and not the FleePath class, therefore I cannot read the “endPoint” location.

fleePath = FleePath.Construct(npc.transform.position, npc.witnessedCrime.transform.position, 10000, OnPathCalculated);

private void OnPathCalculated(Path path)
{
    if (path.error)
    {
        Debug.LogError("Flee path calculation failed: " + path.errorLog);
        return;
    }
//"endPoint" doesn't exist :(
    //npc.SetCustomTarget(path.endPoint);
}

For this version I also tried to cast the Path as a FleePath, but I don’t think the callback is ever being called.

What’s the best way to handle this? Ideally I wouldn’t want to keep enabling and disabling my AIDestinationSetter component and directly do FollowerEntity.SetPath()?

What behavior are you seeing exactly? I just tried this exact thing- FollowerEntity with a FleePath being set as their AIDestinationSetter destination with no issue.

    [Button]
    public void SetFleePath(GameObject fleeFrom){
        var fleePath = FleePath.Construct(transform.position, fleeFrom.transform.position, 10000);
        // follower.SetPath(fleePath);

        GameObject newObj = new GameObject();
        newObj.transform.position = fleePath.endPoint;

        GetComponent<AIDestinationSetter>().target = newObj.transform;
    }
1 Like

If you use ai.SetPath(myFleePath) you’ll need to disable the AIDestinationSetter, as otherwise it will try to override the FleePath immediately afterward.

But you can also do something similar to what @tealtxgr showed.

1 Like

For some reason my “endPoint” is always 0,0,0.

For optimisation reasons i’d prefer to keep the empty transform as the target, and just move it if possible.

Ok, so in the end I had to write my own code which I will share below. I never could figure out why the fleepath was always returning 0,0,0. I did look into it more, and fleePath.IsDone(); was never returning true. Not sure what I was doing wrong.

private Vector3 GetFleePosition(Vector3 startPosition, Vector3 avoidPosition, float fleeDistance)
{
    // Calculate the flee direction
    Vector3 fleeDir = (startPosition - avoidPosition).normalized;
    if (fleeDir == Vector3.zero)
    {
        // Fall back to a random direction if the input is invalid (e.g., overlapping positions)
        fleeDir = Random.insideUnitSphere.normalized;
    }

    // Target position in the opposite direction
    Vector3 rawFleePosition = startPosition + fleeDir * fleeDistance;

    // Use the A* Pathfinding Project to find nearest valid position on navmesh
    NNConstraint nnConstraint = NNConstraint.Walkable;
    GraphNode node = AstarPath.active.GetNearest(rawFleePosition, nnConstraint).node;

    // If valid node found, return its closest point
    if (node != null && node.Walkable)
    {
        return (Vector3)node.position;
    }

    // If no valid flee node is found, fallback to original start position
    return startPosition;
}