"official Way" To Make Agents Avoid Each Other

Googling the question above gives two sort of answers:

  1. using an obstacle component in your agents.

  2. Randomizing the priority of your agent obstacle avoidance.

I was wondering what would be Unity’s official solution on this and what do you use.

Don’t use obstacles on agents, the two components don’t play well together.
Using avoidance priority is the way to go, though I’m not sure what would happen if you’d randomly change that on your agents every few seconds.

I know that both don’t work well together. What they say, is that you only enable the agent when you need to calculate a path, disabling the obstacle, and the switch it the rest of the time. They also say that having the agent enabled all the time is a costly operation (wich sounds wrong to me).

I’m gonna go with the obstacle priority then, quite frankly I’m not seeing any effect. Acording to some you have to randomize the priority, will try that.

This is only partly true. Switch on the NavMeshAgent when your agent needs to walk from A to B. Switch off the NavMeshAgent, when it is standing around for a while and switch the NavMeshObstacle on instead. This will improve the avoidance significantly. Make sure NavMeshAgent and NavMeshObstacle are never active at the same time, as this would indeed not work.

There are some downsides to that approach. When an NavMeshAgent is switched of and a NavMeshObstacle is switched on any agents inside the Obstacle get immediately warped out. So make sure the NavMeshObstacle is not too big and you can also avoid this by using a proxy object for your NavMeshAgent and controlling the positioning yourself with lerping.

Another downside is, if your agents is blocking a narrow passage, while switched off, no one else will be able to path through it.

For a concise explanation how this works check out this older but still valid article:
https://www.gamedev.net/articles/programming/general-and-gameplay-programming/pathfinding-and-local-avoidance-for-rpgrts-games-using-unity-r3703/

2 Likes

I’d add to it that while agents are moving they will be fully dependant on their avoidance priority, meaning if you don’t take care to set those up well your avoidance is going to look significantly worse between moving agents than between a moving and an idling agent.

Yes indeed. I have a system in place where e.g. ranged untis have less priority as they don’t want to get as close to the enemy as a melee unit. I also randomize those archer prios in a certain range, though it can still happen that two archers have the same priority. This can be solved by checking if an agent is stuck for a certain amount of time and temporarily switch of its avoidance or change its avoidance prio.

This is why I would like to have an “official” take on the subject.
You guys must admit that the whole idea of turning off the agent when the character is not moving and turning on an obstacle sounds a lot like a hack. While it may work, probably wasn’t what the people working on Unity had in mind.

4 Likes

I have no idea what people had in mind at Unity, all I can say is that the avoidance code wasn’t touched for ages afaik. The workaround we provided is one solution to the problem, maybe not the best. If you don’t like it you can still write your own avoidance system or use a different plugin like A*/Polarith.

Sorry if what I said sounded rude, it wasn’t my intention at all, I’m very greatful for the answers and both have been a great help.
Is just that after a while of seeing people going with some similar approach, one wonders what was the orginal plan. I haven’t found anything on the docs. If putting an obstacle when the agent was not moving was what they wanted, they’d probably just made that workaround automatic and integreated with the agent. So, I was hoping someone from Unity could clarify how they use the component, that’s all. If there is a better method, we could all profit from it. If there isn’t, then we know we’re using the official one.

3 Likes

Bringing up this topic again.
I have already a big overhead on operations running for the little game I’m making so I’m not planning a proxy system for my Enemy characters, I have a 3D platformer kind of environment, so they switch from agent to walk around, obstacle when standing still, and when hit to rigidbody - in 3 words: a big mess.
What I’m noticing is an incongruence between the update of the navmesh and the scripts updates.
disabling obstacle and enabling agent won’t work without a delay between at least a frame between both.
I finished up trying to use:

yield return new WaitForSeconds(obstacle.carvingTimeToStationary);

and still, on and off Unity prompts me that they are active together (which is impossible!), and I see them jumping around in space.
It would be nice to have at least a delegate function to work with to get the updates of the navmesh, in this way it could be possible to idle the navmesh agent till the obstacle is truly deactivated.

I am now going to try avoidance, thank you for the tips.

Didn’t knew about “carvingTimeToStationary”, sounds useful. But I think the navmesh needs still a frame to be rebuilt or something. I think I used a yield return null or two after the transition from agent to obstacle, and that error went away.
This post is old and I can say that by now I’ve tried many things and got rid of most of the problems but flaws are still there. I think there’s a design problem into this. Some things to look out:

when you make the transition agent-obstacle, you probably have to repath every other agent’s path, as the nav mesh has been changed and the original path may have become obsolete.
The transition agent-obstacle can also carve a hole in the mesh where another agent is walking at the moment. If this happens, the piece of navmesh below the agent’s foot will all of the sudden disappear and it’ll get trapped. You’ll see it run endlessly towards the other one, until the other enemy moves.
There are times where an agent wants to pass between the character obstacle and a wall or corner, and it gets trapped too, there’s another post in the forum about this with a solution that sounds hacky.
I’m still unsure that avoidance is really useful for anything really.
Ultimately, we may have to just check if the character has been stop by another one, throwing a ray. Or repath every frame. Quite a mess.

I still strongly believe that Unity should explain how it’s suppouse to be done.

4 Likes

To add to this, why are you carving the Navmesh with the Navmesh obstacle? I leave carving off which forces other agent to move around them.
I see no downsides (at least for my game),

if you leave carving off, is that not the same as having higher ObsticleAvoidancePriority? (by Higher, I mean lower value ofc). I say this because, lower Priority units cannot push/budge Higher priority Units.

Unity Explains it Like this:

But the Most Important point I think is this:

So obstacle avoidance works great until you have NavMeshObstacles carving the NavMesh. Is there a way to set a priority for NavMeshObstacle? Like I want my NavAgents to avoid each other, but not to try and avoid obstacles that are already carving the NavMesh how I want.

The major problem I’m seeing when I turn Obstacle Avoidance Quality to High is that it causes my NavAgent to slow down around corners, which I don’t want (not even sure why this is happening?) But when I set Obstacle Avoidance Quality to None my NavAgent doesn’t slow down around corners.

I ended up here through google because I forgot how I did agent avoidance in the first place.
I have agent A, who can move through all agent B. But if I have 2 agent A’s alive, they will eventually stack inside of one another. So my problem was to make it so agent A could still move through agent B, without stacking in place.
That solution was set Obstacle Avoidance Quality to NONE on agent A, and LOW on agent B.

To resolve the agent A stacking, I used a speed based avoidancePriority. So faster agents now “push” other agents out of the way so they can reach the destination.
Depending on your game I could also see a size-based assignment to avoidancePriority.

Hope this is helpful. And remember as Mortalanimal said, lower numbers mean more important, and cannot be pushed by higher numbers

1 Like

Yeeeewwws! Finally found someone that’s making sense thanks brother I appreciate it…:wink:

Thats the worst possible approach causing more problems than resolving issues with local avoidance.

The thing is local avoidance is completly not working properly, while your set many agents going into comletly different destinations then they avoid each other on the way but try to select (like in RTS) for example 50 agents and set their destination, all fight for that one spot or try set them to attack one enemy (again like in RTS) while having weapon range and their should stop at max distance and shoot while the rest should avoid those already shooting and continue to target till they are in range, if this is not possible then stop closes possible and wait for opportunity to close for shoot.

I made this creating random destination around mouse click and for attack-move i set colliders behind units and while they are shooting collider start to detect other agents bashing while trying to go to target enemy, then those shooting with collider triggered move forward a bit toward target till no agents trigger their back collider.
Hacky way but it works and while work this way we can ask if this should look like this, not better for Unity to focus on improving Navmesh agents functionality in regards local avoidance? All their lack are elements helpfull to develop RTS like games, to revitalize the genre. All i see is Unity see the most popular games and improve Unity towards being usefull for making more clones of that popular games…

1 Like

You are making sense broo, also setting random Target position on mouse click Is a good idea , thanks

I don’t know if this is a good solution or not but after reading this thread and many others, I managed to kind of solve it, at least for my game.
I simply set my following agents radius (under the obstacle avoidance section) a bit bigger than the agent’s size (my agent has a scale of 0.5 so I set the radius to 0.7) and the priority to 0, as Tomasz_Pasterski sugested.
Now my enemy agents follow the player keeping distance from each other. I guess this would also work for an RTS, since the only difference is the destination not being a moving character.