top of page

Week 2 - Flocking Behaviour

A large part of enemy behaviour is going to be based around the movement of prey within the game. Some animals such as Zebras, Ostriches and Giraffes will move in a herd. I will use the fundamentals of flocking to represent the behaviour of the herds of animals within the game.

I began with researching the fundamentals of flocking. I found that there are three key behavioural characteristics of flocking. These are as follows:

Separation: Steer boids to avoid crowding other flockmates.

Alignment: Steer towards the average heading of local flockmates.

Cohesion: Steer to move toward the center of mass of local flockmates.

I started by adding a basic cube to the scene and set it to move towards a random point on the plane. This cube would act as the scout and all others would simply follow. I added boids (depicted as cubes) which would move towards the scouting boid while keeping a minimum distance behind the scout. These following boids were stored in a list. I made the variable defining the number of following boids public which allowed me to test numbers by changing the value in the editor. However, issues arose when the following boids got to the minimum set distance of the scouting boids. Boids would bunch up and movement would fail to be realistic.

I decided to take a new approach to the movement of boids. Instead of moving boids towards the scout, I would move all ‘following’ boids independently towards a specific point at a set speed. The specific point was chosen to be a random point on the plane. Once a single ‘following’ boid reached the destination point, the destination point would regenerate and all boids would move towards the next destination. This would cover the flocking fundamental of alignment.

Simply having this feature however meant that boids would not bunch together when the destination changed. Boids would spread out in all directions.

In order to resolve the issue of boids not moving as a group, I focused on Cohesion where boids would move toward the center of mass. To get the centre position, I summed the Vector 3 (X,Y,Z) position of all boids and divided this by the number of boids present on in the scene. This value was defined as the ‘AverageCenterPoint’. This value was updated every frame. While the boids were moving towards the destination, I set them to move towards the ‘AverageCentrePoint’ at half the defined speed. This mean that all boids were moving towards the destination while moving towards the average CenterPoint.

Although, boids were now moving towards the destination as a group, they often became bunched. The issue can be seen in the picture below.

The final flocking rule I addressed was Seperation. I researched various methods to dynamically separate boids when they came too close in proximity to one another. I tried to use a method which used Unity’s SpringJoin compontent. This worked by adding a SpringJoint to each boid in the list. Using a nested for loop, I attached a SpringJoint to each boid which was in turn attached to all other boids in the list. However, I realised that this was not a viable method upon running the script. I found that all boid positions relative to each other needed to be constantly monitored. This made it extremely computationally intensive. I had to count this attempt of flocking separation with SpringJoints as a failure. An image of the behaviour can be seen below.

After more research I found that Untiy had an inbuilt method which would generate a force on the global coordinate system to an object with a Rigidbody component attached.

I attached a Rigidbody component to all boids and used an if statement which would add a force to boids which were below a certain proximity to one another. In order to define the direction of the force I used a nested for loop to compare boid positions to one another. When two boids were under the proximity threshold, the difference in position (calculated as a Vector3 (X,Y,Z)) of the applicable boids was calculated. This value was then normalised and set to a variable named ‘difference’. I then used the Rigidbody component ‘AddForce’ and used it to add a force using the inverse of the ‘difference’ value. This moved the boids in the opposite direction to which they were currently moving. The force was only added while the objects were below the specified proximity threshold. This herewith concluded the general flocking functionality of my agents.

In the coming weeks, I will be creating animal assets and an environment with obstacles. I will define the Walkable/ Unwalkable areas using Unity’s Navmesh. Using this general flocking behaviour, I will adapt it to function with my created animal assets to move around the Navmesh while traversing around obstacles.


Recent Posts
bottom of page