Skip to content

Instantly share code, notes, and snippets.

@onedayitwillmake
Created August 20, 2013 03:43
Show Gist options
  • Save onedayitwillmake/6276885 to your computer and use it in GitHub Desktop.
Save onedayitwillmake/6276885 to your computer and use it in GitHub Desktop.
Simpld Boid with seeking behavior in C#
using UnityEngine;
using System.Collections;
public class Boid : MonoBehaviour {
// Position
public Vector3 position;
private Vector3 _previousPosition;
// State
private Vector3 _velocity = Vector3.zero;
private Vector3 _acceleration = Vector3.zero;
private Vector3 _steeringForce = Vector3.zero;
public float _radius;
// Wander
public float wanderRadius = 25.0f;
public float wanderLookAheadDistance = 100;
public float wanderMaxTurningSpeed = 35 * Mathf.PI / 180.0f;
private float _wanderTheta;
private float _maxSpeed;
private float _maxSpeedSQ;
public float maxSpeed {
get { return _maxSpeed; }
set { _maxSpeedSQ = value * value; _maxSpeed = value; }
}
private float _maxForce;
private float _maxForceSQ;
public float maxForce {
get { return _maxForce; }
set { _maxForceSQ = value * value; _maxForce = value; }
}
public void Init( Vector3 initialPosition, float aMaxSpeed, float aMaxSteeringForce ) {
position = _previousPosition = initialPosition;
maxSpeed = aMaxSpeed;
maxForce = aMaxSteeringForce;
}
// Use this for initialization
void Start () {
_wanderTheta = Random.value * Mathf.PI * 2;
}
// Update is called once per frame
void Update () {
_previousPosition = position;
_velocity += _acceleration;
if( _velocity.sqrMagnitude > _maxSpeedSQ ) {
_velocity.Normalize();
_velocity *= _maxSpeed;
}
position += _velocity;
_acceleration = Vector3.zero;
}
public void Seek( Vector3 target, float multiplier ) {
_steeringForce = steerTowardsWithEaseDistance( target );
_steeringForce *= multiplier;
_acceleration += _steeringForce;
}
public void Wander( float multiplier ) {
// Randomly turn left or right
_wanderTheta += (Random.value * wanderMaxTurningSpeed*2) - wanderMaxTurningSpeed;
// Add our speed to where we are, plus wanderDistance
// ( How far in front of where we are, we project ourselves when wandering)
// This is a straight line in front of us
Vector3 futurePosition = _velocity.normalized;
futurePosition = (futurePosition*wanderLookAheadDistance) + position;
// Move left or right a little
Vector3 offset = new Vector3( Mathf.Cos(_wanderTheta), Mathf.Sin(_wanderTheta), Mathf.Tan( _wanderTheta ) );
offset *= wanderRadius;
// Steer towards future position
_steeringForce = steerTowardsWithEaseDistance( futurePosition + offset );
_steeringForce *= multiplier;
_acceleration += _steeringForce;
}
public void FleeIfWithinDistance( Vector3 target, float panicDistance, float multiplier ) {
Vector3 delta = position - target;
// We're far enough away not to care
if( delta.sqrMagnitude > panicDistance * panicDistance ) return;
_steeringForce = steerTowardsWithEaseDistance( target, panicDistance );
_steeringForce *= -multiplier;
_acceleration += _steeringForce;
}
Vector3 steerTowardsWithEaseDistance( Vector3 target, float easeDistance = 0.0f ) {
_steeringForce = target - position;
if( _steeringForce.sqrMagnitude > 0.001f ) {
if( easeDistance > 0.0f && _steeringForce.sqrMagnitude < easeDistance*easeDistance ) {
_steeringForce *= _maxSpeed * ( _steeringForce.magnitude / easeDistance );
} else {
_steeringForce *= _maxSpeed;
}
// Offset the current velocity ( why? )
_steeringForce -= _velocity;
// Cap steering force
if( _steeringForce.sqrMagnitude > _maxForceSQ ) {
_steeringForce.Normalize();
_steeringForce *= _maxForce;
}
}
return _steeringForce;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment