Flocking
From Unify Community Wiki
Contents |
[edit] Information
Here's a set of flocking scripts, They will follow a target, have controls for min speed, max speed, randomness.
Uses the physics engine and oversized sphere colliders to keep the boids apart.
Use the example scene in the unityPackage to figure out how to hook it all together.
[edit] Download Package
Download Flocking.unityPackage.zip
C# version by Benoit FOULETIER (basically just converted the original, cleaned up and optimized a bit... the logic is identical.)
[edit] JavaScript - Boid Controller.js
This script creates and collects information on the boids. It Uses the surface of the controller's collider as spawn points.
var minVelocity : float = 5;
var maxVelocity : float = 20;
var randomness : float = 1;
var flockSize : int = 20;
var prefab : GameObject;
var chasee : GameObject;
var flockCenter : Vector3;
var flockVelocity : Vector3;
private var boids;
function Start() {
boids = new Array(flockSize);
for (var i=0; i<flockSize; i++) {
var position = Vector3(
Random.value*collider.bounds.size.x,
Random.value*collider.bounds.size.y,
Random.value*collider.bounds.size.z
) - collider.bounds.extents;
var boid = Instantiate(prefab, transform.position, transform.rotation);
boid.transform.parent = transform;
boid.transform.localPosition = position;
boid.GetComponent("Boid Flocking").setController(gameObject);
boids[i] = boid;
}
}
function Update () {
var theCenter = Vector3.zero;
var theVelocity = Vector3.zero;
for (var boid : GameObject in boids) {
theCenter = theCenter + boid.transform.localPosition;
theVelocity = theVelocity + boid.rigidbody.velocity;
}
flockCenter = theCenter/(flockSize);
flockVelocity = theVelocity/(flockSize);
}
[edit] JavaScript - Boid Flocking.js
Each boid runs this script. It handles randomness, clumping behavior, velocity matching behavior and target following behavior.
This could be updated to include weighting factors for velocity matching, target following and clumping, as has been done for randomness.
var Controller : GameObject;
private var inited = false;
private var minVelocity : float;
private var maxVelocity : float;
private var randomness : float;
private var chasee : GameObject;
function Start () {
StartCoroutine("boidSteering");
}
function boidSteering () {
while(true) {
if (inited) {
rigidbody.velocity = rigidbody.velocity + calc() * Time.deltaTime;
// enforce minimum and maximum speeds for the boids
var speed = rigidbody.velocity.magnitude;
if (speed > maxVelocity) {
rigidbody.velocity = rigidbody.velocity.normalized * maxVelocity;
} else if (speed < minVelocity) {
rigidbody.velocity = rigidbody.velocity.normalized * minVelocity;
}
}
waitTime = Random.Range(0.3, 0.5);
yield WaitForSeconds(waitTime);
}
}
function calc () {
var randomize = Vector3((Random.value *2) -1, (Random.value * 2) -1, (Random.value * 2) -1);
randomize.Normalize();
flockCenter = Controller.GetComponent("Boid Controller").flockCenter;
flockVelocity = Controller.GetComponent("Boid Controller").flockVelocity;
follow = chasee.transform.localPosition;
flockCenter = flockCenter - transform.localPosition;
flockVelocity = flockVelocity - rigidbody.velocity;
follow = follow - transform.localPosition;
return (flockCenter + flockVelocity + follow*2 + randomize*randomness);
}
function setController (theController : GameObject) {
Controller = theController;
minVelocity = Controller.GetComponent("Boid Controller").minVelocity;
maxVelocity = Controller.GetComponent("Boid Controller").maxVelocity;
randomness = Controller.GetComponent("Boid Controller").randomness;
chasee = Controller.GetComponent("Boid Controller").chasee;
inited = true;
}
[edit] JavaScript - Boid Watcher.js
A camera script, watches the center of the flock.
var boidController : Transform;
function LateUpdate () {
if (boidController) {
var watchPoint : Vector3 = boidController.GetComponent("Boid Controller").flockCenter;
transform.LookAt(watchPoint+boidController.transform.position);
}
}
