Hi, I have been playing around with NavMesh and NavMeshAgents and ran into a problem.
I made some simple movement scripts trying to move a group of agents as a formation or blob. I’m setting the same destination for all of them so they push each other trying to get there. When they are close enough to the destination I reset their path, and also when they are close enough to another agent that already stopped. So eventually they all stop in a sort of blobby line all nearby each other.
This works well up until about 70-100 agents, and then they start overlapping and randomly “popping” like popcorn. It looks as if “other agent avoidance” doesn’t run for all of the agents. However it doesn’t seem to be a speed thing, because after all agents stop the overlaps that remain never correct themselves.
I recorded a video (of a different script excample) where I just spawn agents really close to each other without a destination, so they just push each other until they are not overlapping. Again with 50 agents or so it works, but then they start overlapping and popping:
30 agents working correctly: xkd2t
100 agents popping: z6zc5
I also found this video online (which is from march 2018):
where on the 2nd entry to the maze from the left at 1:12 you can see this happening (might want to slow down the video to 0.25x).
I’m using mostly default settings on the navmesh and agents. I’m only changing speed to 12 and acceleration to 60.
I can only give you a guess.
All agents want to be in the center, so all of them push in that direction, this is constant.
They are repel other agents with a given force, but when enough agents push in the same direction the force is enough to overcome the avoidance.
A similar issue happens when a bunch of agents want to go through a wall (and the wall does not carve the navMesh) if enough agents push, eventually some of them will pop through.
You could try spacing out the positions (by precalculating them depending on the number of agents); making agents carve ground when they stay still (this will not solve popping, it’ll probably make it worse, but will probably solve overlapping).
I have a similar problem, I was able to reduce this effect by placing a non-Kinematic RgididBody with discrete collision detection that has a smaller radius than the navmesh obstacle avoidance radiance, this is more taxing, and is some situation can give you weird behaviour, such as your units can start spinning if they collide with another rigidbody (I solved this by making sure my units know which direction to face every 0.1s)… anyway, I dont like my solution, so please if you find a fix, tag me in the answer! thank you…
Also, I think it has something to do with processing power, because the same thing happens to me but only when I exceed 150 units.
I also Have a hunch that this setting may effect it, but I have yet to test it:
Here is my code for that. I’m using trigger colliders on each agent with a bigger radius than the obstacle avoidance radius to trigger the interaction. However, you could use kd trees or another method of finding nearby agents if you wanted to get rid of colliders.
// check if path is valid and im close enough to stop
if (!reachedDestination && agent.hasPath && !agent.pathPending && agent.remainingDistance < 0.5f)
{
reach_destination();
} else
{
// check if im inside the 'compact' formation area
if (Vector3.Distance(this.transform.position, formation._formation_center_waypoint.transform.position) <= formation.formation_size())
{
Collider[] hitColliders = Physics.OverlapSphere(this.transform.position, 0.7f);
for (int i = 0; i < hitColliders.Length; ++i)
{
Droid other = hitColliders[i].gameObject.GetComponent<Droid>();
// if im near someone that already stopped, ill stop as well instead of pushing on
if (other != null && other.formation != null && this.formation != null && other.reachedDestination)
{
reach_destination();
break;
}
}
}
}
void reach_destination()
{
reachedDestination = true;
agent.velocity = Vector3.zero;
agent.ResetPath();
}
And a video:
5b03e
This is using NavMeshAgent to do the pathfinding and the movement. I’m only setting each agents destination to the same waypoint behind the player. You can see that as you keep moving the formation stars loosing the circular shape and becoming a line. I’m trying to force the circular shape by only allowing agents to stop if they are inside a radius nearby the goal, but it still looks a bit weird as the ones at the back try to push forward (especially in narrow corridors)
thanks bro much appreciate it, maybe u should add a delay before u stop the units that are in-proximity to a static (as in non-mobile) unit. Just suggesting this to avoid the narrow path problem from the video
Thanks so much! This solved my problem too. However on my pc with 0.5 the agents eventually fix themselves, but the popping is still visible. I’m now using a really small value of 1e-07 and agents push each other away much more gradually. They still overlap when there are many bunched up, but they “slide” away instead of popping.
bn75d
According to the Unity docs:
So it makes sense, with a large value agents wait too long to avoid each other and they end up overlapping and popping. And I guess once they overlap too much they don’t even detect it as a collision because they are on top of each other?
Thanks, this makes sense now. I saw this happen with boids and steering behaviours where one behaviour (like getting to destination) can overpower the others (like avoidance). But I thought Unity using RVO meant that they guaranteed avoidance with linear programming. I guess it only means they build velocity obstacles and use a force-based method to keep agents separated.