#StackBounty: #unity #c# #path-finding Queueing with Unity's NavMeshAgent

Bounty: 100

I have created a strategy game where the units use Unity’s NavAgent pathfinding and flocking algorithms. This works well. However, I need to add queueing so that units will queue sensibly. This works most of the time, but it isn’t perfect and I want to know if there’s a better way of doing it.

My first draft was to simply check which unit is closest to the destination, but this caused issues because a group might be navigating around an obstacle and the unit closest is at the back of the queue… so the whole group stops.

Second draft checked the distance to destination based upon the length of the path each unit had to take. This works far more often, but sometimes still has issues. Sometimes the same problem happens, but much less often. Below is the relevant code.

There’s also a problem I’ve noticed, where the waiting units could sometimes benefit from rotating, even if they shouldn’t be moving. Unfortunately they sometimes get stuck and will wait before they can move, to rotate. If they could rotate when forbidden from moving it’d help considerably too.

Unit Movement Function

private void Movement()
{
    // Unit is moving.
    if (moveVectors.Count > 0)
    {
        navAgent.isStopped = false;

        // Check for whether to wait in queue.
        Vector3 nextVector = transform.position;
                nextVector += transform.forward * speed * Time.deltaTime;

        foreach (Unit unit in list)
        {
            if (unit != this &&
                unit.moveVectors.Count > 0 &&
                Vector3.Distance(unit.transform.position, nextVector) <= (unit.footprint + footprint) &&
                PathDistance(unit) < PathDistance(this))
            {
                navAgent.isStopped = true;
                return;
            }
        }
    }
}

There’s a bit more to Movement, but it’s not relevant so we’ll ignore it for now.

PathDistance Function

private float PathDistance(Unit unit)
{
    Vector3 startPosition = unit.transform.position;
    Vector3 endPosition = unit.moveVector;
    Vector3 lastPosition = startPosition;
    Vector3[] path = unit.navAgent.path.corners;
    float distance = 0;

    for (int i = 0; i < path.Length; i++)
    {
        distance += Vector3.Distance(lastPosition, path[i]);
        lastPosition = path[i];
    }

    distance += Vector3.Distance(lastPosition, endPosition);
    return distance;
}

Is there a better way of achieving the result I want?


Get this bounty!!!

Leave a Reply