RVO obstacle performance and prolems

Hi to all,
I’m making big city simulation with 1000+ agents with grid-graph. Local Avoidance works great, but when i add colliders (and city need a lot of them, at least hundred) there is huge impact on performance and large crowds pushes agents “inside” of obstacles and they cannot get out.

I have written my own movement AI, because RichAI and other are too heavy on processing. Is there some way to make agents avoid walls without obstacles? I could write my own raycast-based obstacle detection, but if there is some already done solution for this, i would be happy to hear it :slight_smile:

Rigidbodies have to be off too, because it also is too heavy for CPU on 1000+ bodies.

Thanks for any help that you could provide!


Which version are you using? The 4.x version should be significantly more resistant to agents ending up inside obstacles, though it is unfortunately not impossible.

Unfortunately RVO obstacles are currently not as optimized as they could be. This means that obstacles will have a performance impact even when they are far away from an agent.
In any case, even if they were optimized for that use case, I think they might be too slow for you anyway since 1000+ agents is a lot and RVO obstacles are comparatively slower for the local avoidance algorithm compared to regular agents. If physics is also too slow for you I think it might be worthwhile to implement a very simple and fast collision detection system just to push agents out of obstacles. To make it integrate better with RVO you can use the RVOController.SetCollisionNormal method.

If you are ok with an additional 1-frame delay in how quickly RVO agents react, I would recommend enabling the ‘Double Buffering’ option on the RVOSimulator component, as well as of course using multithreading.

I’m using 4.0.11 just bought your pro-version couple of days ago so all is new and shiny to me :slight_smile:

Is there any example-code for SetCollisionNormal that is integrated to some simple collision detection system?

Currently that method is only used in a single place. It is used in the RichAI.ClampToNavmesh method to make sure the RVO system knows about navmesh borders. The RichAI script will clamp the AI to the navmesh every frame.

The SetCollisionNormal method takes a normal (wikipedia), so essentially you just have to set it to the normal of the surface it is colliding with. For example if it is colliding with a wall to the right, that wall will have a normal pointing left, so if you call SetCollisionNormal(Vector3.left) then the agent will not try to penetrate the wall too much.

I’d recommend getting the rest to work first though. The side effects of not using the SetCollisionNormal method is that units may get squished together near obstacles as they assume that the units in front of them will move away (but they can’t, because there is an obstacle in the way).