Our Flow Field is now of reasonable quality, before we look at adding in more improvements for it we need to add Physics to our simulation so that it is more like something you’d see in a game, and so we can properly verify our Flow Field changes improve the real case.
The first step of this is to remove our custom Vector2 class and replace it with the Box2d B2Vec2, you can check out a diff on github of how this went.
To implement the physics we need to create a Box2D world (the object that hosts the physics simulation) and create a B2Body for each of the agents. We also need to remove the custom physics code that we previously had to move agents in response to their steering forces, instead relying on box2D to move our agents.
I’m not going to show all of the changes, you can check out the commit on github.
With this in, the Agents will collide with each other as they attempt to follow the flow field, but they can still go through the impassable areas. To stop that, we need to give them physics bodies also, this looks the same as above, except we create a static body instead of a dynamic one (meaning the obstacles don’t move) and we create a square rather than a circle. See github for the commit
If you run this revision, you’ll encounter behaviour like this: Multiple Agents are trying to take the same path, but they jam against each other and hold up everyone behind them.
To try solve this, I first added the flocking behaviours back in. This helped, but the situation would still occur. So I looked to Planetary Annihilation for inspiration.
From my observations, it would appear that they do not use a ‘hard’ physics simulation (at least not exclusively). Units appear to be allowed to get a bit closer to their neighbours than their size would allow, there is a force pushing them away, but it is not a hard constraint.
You can reproduce this if you make a large group of units move through a small gap. Or by just moving a large group of units a short distance, once they arrive at their destination they will spread out a small amount.
To implement something like follows. First, reduce the size of the physics bodies for the agents to 1/2 of their real size. This allows them to appear to overlap (really they are just smaller than they appear). Then use the Separation behaviour to apply a force to try keep out of other Agents real radius.
With this in place, agents will stay at their normal true radius distance when travelling free from obstacles, but when necessary they will get a bit closer, allowing them to squeeze through tight gaps together.
I’m not sure if this is actually what is implemented in Planetary Annihilation, but it appears to have the same behaviour, so that’s good enough for me :-)
From here I did some further tuning of the behaviour weights and the physics config. I’ve set restitution and friction on on the agents to 0 so they don’t drag when moving against walls, and so they don’t bounce off each other if they collide.
With these changes in place, everything looks pretty good. Check out the Updated Example.
At the end of the path they will overlap as they are all trying to fit in to a small area. We’ll fix this later by having Agents stop following the flow field when they have reached their destination (or when they collide with someone who has).
We still have other issues that I believe SupCom2/PA have solved, using other techniques from the Continuum Crowds paper:
- Agents don’t try and avoid congested paths
- Multiple groups of agents won’t path around each other
Once I’ve done some more reading on Continuum Crowds I’ll look at implementing this in a future article :)