1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| using UnityEngine;
namespace WithPhysic { public class Boid { BoidSettings settings;
public Vector3 position; public Vector3 forward; Vector3 velocity;
Vector3 acceleration; public Vector3 avgFlockHeading; public Vector3 avgAvoidanceHeading; public Vector3 centreOfFlockmates; public int numPerceivedFlockmates;
Transform cachedTransform; Transform target;
public void Init (BoidSettings settings, Transform target, GameObject goInst) { this.target = target; this.settings = settings; this.cachedTransform = goInst.transform;
position = cachedTransform.position; forward = cachedTransform.forward;
float startSpeed = (settings.minSpeed + settings.maxSpeed) / 2; velocity = cachedTransform.forward * startSpeed; }
public void UpdateBoid () { Vector3 acceleration = Vector3.zero;
if (target != null) { Vector3 offsetToTarget = (target.position - position); acceleration = SteerTowards (offsetToTarget) * settings.targetWeight; }
if (numPerceivedFlockmates != 0) { centreOfFlockmates /= numPerceivedFlockmates;
Vector3 offsetToFlockmatesCentre = (centreOfFlockmates - position);
var alignmentForce = SteerTowards (avgFlockHeading) * settings.alignWeight; var cohesionForce = SteerTowards (offsetToFlockmatesCentre) * settings.cohesionWeight; var seperationForce = SteerTowards (avgAvoidanceHeading) * settings.seperateWeight;
acceleration += alignmentForce; acceleration += cohesionForce; acceleration += seperationForce; }
if (IsHeadingForCollision ()) { Vector3 collisionAvoidDir = ObstacleRays (); Vector3 collisionAvoidForce = SteerTowards (collisionAvoidDir) * settings.avoidCollisionWeight; acceleration += collisionAvoidForce; }
velocity += acceleration * Time.deltaTime; float speed = velocity.magnitude; Vector3 dir = velocity / speed; speed = Mathf.Clamp (speed, settings.minSpeed, settings.maxSpeed); velocity = dir * speed;
cachedTransform.position += velocity * Time.deltaTime; cachedTransform.forward = dir; position = cachedTransform.position; forward = dir; }
bool IsHeadingForCollision () { RaycastHit hit; if (Physics.SphereCast (position, settings.boundsRadius, forward, out hit, settings.collisionAvoidDst, settings.obstacleMask)) { return true; } else { } return false; }
Vector3 ObstacleRays () { Vector3[] rayDirections = Help.DIRECTIONS;
for (int i = 0; i < rayDirections.Length; i++) { Vector3 dir = cachedTransform.TransformDirection (rayDirections[i]); Ray ray = new Ray (position, dir); if (!Physics.SphereCast (ray, settings.boundsRadius, settings.collisionAvoidDst, settings.obstacleMask)) { return dir; } }
return forward; }
Vector3 SteerTowards (Vector3 vector) { Vector3 v = vector.normalized * settings.maxSpeed - velocity; return Vector3.ClampMagnitude (v, settings.maxSteerForce); } } }
|