0

I am currently working on a Unity3D Game and I ran in some problems with the nav mesh agents. My current objective is to get enemies to walk towards the closest player (there will be 3). One I spawn an enemy it will check for itself which of the players is closest. This is done with the remaining distance towards the player as seen in the code below

agent.CalculatePath(player.transform.position, path);
agent.Stop();
agent.SetPath(path);

if (distance > agent.remainingDistance)
{
    distance = agent.remainingDistance;
    playerToFollow = player;
} 

In this snippet the distance will start at ‘float.MaxValue’ and will (whenever a player is closer than the current distance be set as ‘playerToFollow’, which is a GameObject.

The problem lies here: When the path to the player has 0 or 1 corners. The nav mesh agent will start walking its path towards the player. BUT… whenever the path contains more than 1 corner, the distance will not be calculated, thus returning agent.remainingDistance == float.PositiveInfinity.

this means that distance (which is float.MaxValue) is less then remaining distance (float.PositiveInfity).

Any things I might forget? Please let me know. I can always provide more details .

Marcel
  • 228
  • 1
  • 5
  • 12
  • `NavMeshAgent.remainingDistance` will return infinity when the distance is unknown. Are you certain both the agent and the player are always on the navmesh? – Serlite Oct 25 '16 at 18:42
  • Yes. The part of my team that is implementing the player controlls is still working on it. The objects being tagged as player are not moving and always grouned. The Enemies i can place spawn on a plane and both the enemies that can walk and that cant are on the same Y position. – Marcel Oct 25 '16 at 19:12
  • 1
    On a side note, it is possible that `remainingDistance` is not updated until the frame after the path is initially assigned - try checking it in the `Update()` method after the path is assigned (if this check is currently only done once), and see if its value ever changes to something more useful. Otherwise, you can stick with your existing solution if it works acceptably. – Serlite Oct 26 '16 at 14:12

1 Answers1

1

I fixed it by not using the distance in the agent. I am now using the path corners and calculating the distance between those.

 players.ForEach(
        player =>
        {
            agent.CalculatePath(player.transform.position, path);
            float pathDistance = calculatePathDistance(path);

            if (pathDistance < distance)
            {
                distance = pathDistance;
                playerToFollow = player;
            }

        }
    );

with the implementation of #calculatePathDistance(NavMeshPath path) being like:

private float calculatePathDistance(NavMeshPath path)
{
    float distance = .0f;
    for (var i = 0; i < path.corners.Length -1; i++)
    {
        distance += Vector3.Distance(path.corners[i], path.corners[i + 1]);
    }
    return distance;
}

If you have a way where the agent.remainingDistance works, please let me know.

Marcel
  • 228
  • 1
  • 5
  • 12
  • I can see your approach is polling existing path agents. I would like to perform this for a single agent within a frame to evaluate a potential path. It would not seem possible. Perhaps there is a way to force the calculation within the frame. – mrVentures May 30 '20 at 23:34