GitHub

Untitled

In 1986, Craig Reynolds created a model to describe the motion of flocks. These flocks recreated the motion of animals that move in groups, such as fish or birds, and he called these simulated animals boids. With three simple rules, this model creates very naturalistic motion. What follows is a summary of my implementation of this model, using C# and Unity.

Three Simple Rules

Our base representation of our boids without any behavior will be them just moving in some initial direction with some initial speed. The boid would move along this velocity vector infinitely, never changing direction. With Reynolds' three simple rules, we can add behavior to this motion, and life to the boids. The three rules are as follows

  1. Separation

    Steering away from neighboring boids that are too close.

  2. Alignment

    Steering towards the average of the velocities of all neighboring boids.

  3. Cohesion

    Steering towards the center of mass of all neighboring boids.

With these rules, we can start with the implementation.

Unity Setup and the First Problem to Solve

I started by jumping in Unity, getting my scene setup, and creating a BoidController class that sets its initial velocity to some random unit vector. I'm going to assume this is a baseline thing for anyone reading this, if you need help getting this far, there are plenty of Unity tutorials on YouTube. Otherwise, if you've set up a character controller before, this will follow in the same vein.

Also created a FlockController class, which is responsible for creating the boids when you hit play. I used a List of GameObjects to store references to these boids, which we'll need so we can find a list of our neighbors.

void Start() {
        for (int i = 0; i < settings.numBoids; i++) {
            BoidController boid = Instantiate(settings.boidPrefab).GetComponent<BoidController>();
            boid.Initialize(settings);
            boids.Add(boid);
        }
}

You'll note I'm using some settings objects to get all of these parameters. This is a ScriptableObject I created called BoidsSettings, which is designed to represent all of our parameters for the boids and flock.

Our first problem here is that the boids just move along their initial velocity vector, so the first problem was to contain the boids in some volume, or create some bounds for our simulation. For this, we need a minimum range for the boids, which will let us know how close the boids are allowed to get to the edge, and a max range, which will create a sphere centered on the origin, which represents our bounds for the simulation. Here's my commented code for this: