Controlling the object group movement through flocking

A realistic, natural-looking, flocking behavior (for example birds or antelopes or bats) can be created through creating collections of objects with the following four simple rules:

  • Separation: Avoiding getting too close to neighbors
  • Avoid Obstacle: Turning away from an obstacle immediately ahead
  • Alignment: Moving in the general direction the flock is heading
  • Cohesion: Moving towards the location in the middle of the flock

Each member of the flock acts independently, but needs to know about the current heading and location of the members of its flock. This recipe shows you how to create a scene with two flocks of cubes: one flock of green cubes and, one flock of yellow cubes. To keep things simple, we'll not worry about separation in our recipe.

Controlling the object group movement through flocking

Getting ready

This recipe builds upon the player-controlled cube Unity project that you created in the first recipe. So, make a copy of this project, open it, and then follow the steps for this recipe.

How to do it...

To make a group of objects flock together, please follow these steps:

  1. Create a Material in the Project panel, and name it as m_green with the Main Color tinted green.
  2. Create a Material in the Project panel, and name it as m_yellow with Main Color tinted yellow.
  3. Create a 3D Cube GameObject named Cube-drone at (0,0,0). Drag the m_yellow Material into this object.
  4. Add a Navigation | NavMeshAgent component to Cube-drone. Set the Stopping Distance property of the NavMeshAgent component to 2.
  5. Add a Physics RigidBody component to Cube-drone with the following properties:
    • Mass is 1
    • Drag is 0
    • Angular Drag is 0.05
    • Use Gravity and Is Kinematic are both unchecked
    • Under Constrains Freeze Position for the Y-axis is checked
  6. You will see the following Inspector values for your cube's rigid body component:
    How to do it...
  7. Create the following C# script class called Drone, and add an instance as a component to the Cube-drone GameObject:
    using UnityEngine;
    using System.Collections;
    
    public class Drone : MonoBehaviour {
      private NavMeshAgent navMeshAgent;
    
      void Start() {
        navMeshAgent = GetComponent<NavMeshAgent>();
      }
    
      public void SetTargetPosition(Vector3 swarmCenterAverage, Vector3 swarmMovementAverage) {
        Vector3 destination = swarmCenterAverage + swarmMovementAverage;
        navMeshAgent.SetDestination(destination);
      }
    }
  8. Create a new empty Prefab named dronePrefabYellow, and from the Hierarchy panel, drag your Cube-boid GameObject into this Prefab.
  9. Now, drag the m_green Material into the Cube-boid GameObject.
  10. Create a new empty Prefab named dronePrefabGreen, and from the Hierarchy panel, drag your Cube-drone GameObject into this Prefab.
  11. Delete the Cube-drone GameObject from the Scene panel.
  12. Add the following C# script Swarm class to the Main Camera:
    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public class Swarm : MonoBehaviour {
      public int droneCount = 20;
      public GameObject dronePrefab;
    
      private List<Drone> drones = new List<Drone>();
    
      void Awake() {
        for (int i = 0; i < droneCount; i++)
          AddDrone();
      }
    
      void FixedUpdate() {
        Vector3 swarmCenter = SwarmCenterAverage();
        Vector3 swarmMovement = SwarmMovementAverage();
    
        foreach(Drone drone in drones)
          drone.SetTargetPosition(swarmCenter, swarmMovement);
      }
    
      private void AddDrone() {
        GameObject newDroneGO = (GameObject)Instantiate(dronePrefab);
        Drone newDrone = newDroneGO.GetComponent<Drone>();
        drones.Add(newDrone);
      }
    
      private Vector3 SwarmCenterAverage() {
        // cohesion (swarm center point)
        Vector3 locationTotal = Vector3.zero;
    
        foreach(Drone drone in drones)
          locationTotal += drone.transform.position;
    
        return (locationTotal / drones.Count);
      }
    
      private Vector3 SwarmMovementAverage() {
        // alignment (swarm direction average)
        Vector3 velocityTotal = Vector3.zero;
    
        foreach(Drone drone in drones)
          velocityTotal += drone.rigidbody.velocity;
    
        return (velocityTotal / drones.Count);	
      }
    }
  13. With Main Camera selected in the Hierarchy panel, drag prefab_boid_yellow, from the Project panel, over the public variable of Drone Prefab.
  14. With Main Camera selected in the Hierarchy panel, add a second instance of the script class called Swarm to this GameObject, and then drag prefab_boid_green, from the Project panel, over the public variable of Drone Prefab.
  15. Create a new Cube named wall-left with the following properties:
    • Position = (-15, 0.5, 0)
    • Scale = (1, 1, 20)
  16. Duplicate the wall-left object by naming the new object as wall-right, and change the position of wall-right to (15, 0.5, 0).
  17. Create a new Cube named as wall-top with the following properties:
    • Position = (0, 0.5, 10)
    • Scale = (31, 1, 1)
  18. Duplicate the wall-top object by naming the new object as wall-bottom, and change the position of wall-bottom to (0, 0.5, -10).
  19. Create a new Sphere named as Sphere-obstacle with the following properties:
    • Position = (5, 0, 3)
    • Scale = (10, 3, 3)
  20. In the Hierarchy panel, select the Sphere-obstacle GameObject. Then in the Navigation panel, check the Navigation Static checkbox. Then, click on the Bake button at the bottom of the Navigation panel.
  21. Finally, make the player's red cube larger by setting its scale to (3,3,3).

How it works...

The Swarm class contains three variables:

  • droneCount: It is an integer referencing the number of the Swarm class members created
  • dronePrefab: It references to the Prefab to be cloned to create swarm members
  • Drone: A list of objects that reference drones, a list of all the scripted Drone components inside all the Swarm objects that have been created

Upon creation, as the scene starts, the Swarm script class Awake() method loops to create droneCount swarm members by repeatedly calling the AddDrone() method. This method instantiates a new GameObject from the prefab, and then sets the newDrone variable to be a reference to the Drone-scripted object, inside the new Swarm class member. In each frame, the FixedUpdate() method loops through the list of Drone objects by calling their SetTargetPosition(…) method, and passing in the Swarm center location and the average of all the swarm member velocities.

The rest of this Swarm class is made up of two methods: one (SwarmCenterAverage) returns a Vector3 object, representing the average position of all the Drone objects, and the other (SwarmMovementAverage) returns a Vector3 object, representing the average velocity (movement force) of all the Drone objects as described in the following list.

  • SwarmMovementAverage():
    • What is the general direction that the swarm is moving in?
    • This is known as alignment—a swarm member attempting to move in the same direction as the swarm average
  • SwarmCenterAverage():
    • What is the center position of the swarm?
    • This is known as cohesion—a swarm member attempting to move towards the center of the swarm

The core work is undertaken by the Drone class. Each drone's Start(…) method finds and caches a reference to its NavMeshAgent component.

Each drone's UpdateVelocity(…) method takes as input two Vector3 arguments: swarmCenterAverage and swarmMovementAverage. This method then calculates the desired new velocity for this Drone (by simply adding the two vectors), and then uses the result (a Vector3 location) to update the NavMeshAgent's target location.

There's more...

There are some details that you don't want to miss.

Learn more about flocking Artificial Intelligence

Most of the flocking models in modern computing owe much to the work of Craig Reynolds in the 1980s. Learn more about Craig and his boids program at http://en.wikipedia.org/wiki/Craig_Reynolds_(computer_graphics).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.42.9