using UnityEngine; public class Boid : MonoBehaviour { public Vector3 velocity; private float cohesionRadius = 10; private float separationDistance = 5; private Collider[] boids; private Vector3 cohesion; private Vector3 separation; private int separationCount; private Vector3 alignment; private float maxSpeed = 15; private void Start() { InvokeRepeating("CalculateVelocity", 0, 0.1f); } void CalculateVelocity() { velocity = Vector3.zero; cohesion = Vector3.zero; separation = Vector3.zero; separationCount = 0; alignment = Vector3.zero; boids = Physics.OverlapSphere(transform.position, cohesionRadius); foreach (var boid in boids) { cohesion += boid.transform.position; alignment += boid.GetComponent<Boid>().velocity; if (boid != collider && (transform.position - boid.transform.position).magnitude < separationDistance) { separation += (transform.position - boid.transform.position) / (transform.position - boid.transform.position).magnitude; separationCount++; } } cohesion = cohesion / boids.Length; cohesion = cohesion - transform.position; cohesion = Vector3.ClampMagnitude(cohesion, maxSpeed); if (separationCount > 0) { separation = separation / separationCount; separation = Vector3.ClampMagnitude(separation, maxSpeed); } alignment = alignment / boids.Length; alignment = Vector3.ClampMagnitude(alignment, maxSpeed); velocity += cohesion + separation * 10 + alignment * 1.5f; velocity = Vector3.ClampMagnitude(velocity, maxSpeed); } void Update() { if (transform.position.magnitude > 25) { velocity += -transform.position.normalized; } transform.position += velocity * Time.deltaTime; Debug.DrawRay(transform.position, separation, Color.green); Debug.DrawRay(transform.position, cohesion, Color.magenta); Debug.DrawRay(transform.position, alignment, Color.blue); } }
if (velocity != Vector3.zero && transform.forward != velocity.normalized) { transform.forward = Vector3.RotateTowards(transform.forward, velocity, 10, 1); }
var boid = Instantiate(boidPrefab, Random.insideUnitSphere * 25, Quaternion.identity) as Transform; boid.parent = transform;
var vector = transform.position - boid.transform.position; if (boid != collider && vector.magnitude < separationDistance) { separation += vector / vector.magnitude; separationCount++; }
if (boid != collider && vector.sqrMagnitude < separationDistance * separationDistance) { separation += vector / vector.sqrMagnitude; separationCount++; } … if (transform.position.sqrMagnitude > 25 * 25) { velocity += -transform.position.normalized; }
public Transform tr; void Awake() { tr = transform; }
foreach (var boid in boids) { var b = boid.GetComponent<Boid>(); cohesion += b.tr.position; alignment += b.velocity; if (vector.sqrMagnitude > 0 && (tr.position - b.tr.position).magnitude < separationDistance) { separation += (tr.position - b.tr.position) / (tr.position - b.tr.position).magnitude; separationCount++; } }
private int maxBoids = 5; … boids = Physics.OverlapSphere(tr.position, cohesionRadius); if (boids.Length < 2) return; … for (var i = 0; i < boids.Length && i < maxBoids; i++) { var b = boids[i].GetComponent<Boid>(); cohesion += b.tr.position; alignment += b.velocity; var vector = tr.position - b.tr.position; if (vector.sqrMagnitude > 0 && vector.sqrMagnitude < separationDistance * separationDistance) { separation += vector / vector.magnitude; separationCount++; } } cohesion = cohesion / (boids.Length > maxBoids ? maxBoids : boids.Length);
public int turnSpeed = 10; public int maxSpeed = 15; public float cohesionRadius = 7; public int maxBoids = 10; public float separationDistance = 5; public float cohesionCoefficient = 1; public float alignmentCoefficient = 4; public float separationCoefficient = 10; public float tick = 2; [HideInInspector] public Vector3 velocity; [HideInInspector] public Transform tr; … InvokeRepeating("CalculateVelocity", 0, tick);
InvokeRepeating("CalculateVelocity", Random.value * tick, tick);
velocity = Random.onUnitSphere * maxSpeed;
var b = boids[i].GetComponent<Boid>(); … var vector = tr.position - b.tr.position;
private Boid b; private Vector3 vector; private int i;
velocity += -tr.position.normalized;
velocity += -tr.position/25;
InvokeRepeating("UpdateRotation", Random.value, 0.1f); … void UpdateRotation() { if (velocity != Vector3.zero && model.forward != velocity.normalized) { model.forward = Vector3.RotateTowards(model.forward, velocity, turnSpeed, 1); } }
public LayerMask boidsLayer; … boids = Physics.OverlapSphere(tr.position, cohesionRadius, boidsLayer.value);
public Transform model; … if (velocity != Vector3.zero && model.forward != velocity.normalized) { model.forward = Vector3.RotateTowards(model.forward, velocity, turnSpeed, 1); }
using UnityEngine; public class Boid : MonoBehaviour { public int turnSpeed = 10; public int maxSpeed = 15; public float cohesionRadius = 7; public int maxBoids = 10; public float separationDistance = 5; public float cohesionCoefficient = 1; public float alignmentCoefficient = 4; public float separationCoefficient = 10; public float tick = 2; public Transform model; public LayerMask boidsLayer; [HideInInspector] public Vector3 velocity; [HideInInspector] public Transform tr; private Collider[] boids; private Vector3 cohesion; private Vector3 separation; private int separationCount; private Vector3 alignment; private Boid b; private Vector3 vector; private int i; void Awake() { tr = transform; velocity = Random.onUnitSphere*maxSpeed; } private void Start() { InvokeRepeating("CalculateVelocity", Random.value * tick, tick); InvokeRepeating("UpdateRotation", Random.value, 0.1f); } void CalculateVelocity() { boids = Physics.OverlapSphere(tr.position, cohesionRadius, boidsLayer.value); if (boids.Length < 2) return; velocity = Vector3.zero; cohesion = Vector3.zero; separation = Vector3.zero; separationCount = 0; alignment = Vector3.zero; for (i = 0; i < boids.Length && i < maxBoids; i++) { b = boids[i].GetComponent<Boid>(); cohesion += b.tr.position; alignment += b.velocity; vector = tr.position - b.tr.position; if (vector.sqrMagnitude > 0 && vector.sqrMagnitude < separationDistance * separationDistance) { separation += vector / vector.sqrMagnitude; separationCount++; } } cohesion = cohesion / (boids.Length > maxBoids ? maxBoids : boids.Length); cohesion = Vector3.ClampMagnitude(cohesion - tr.position, maxSpeed); cohesion *= cohesionCoefficient; if (separationCount > 0) { separation = separation / separationCount; separation = Vector3.ClampMagnitude(separation, maxSpeed); separation *= separationCoefficient; } alignment = alignment / (boids.Length > maxBoids ? maxBoids : boids.Length); alignment = Vector3.ClampMagnitude(alignment, maxSpeed); alignment *= alignmentCoefficient; velocity = Vector3.ClampMagnitude(cohesion + separation + alignment, maxSpeed); } void UpdateRotation() { if (velocity != Vector3.zero && model.forward != velocity.normalized) { model.forward = Vector3.RotateTowards(model.forward, velocity, turnSpeed, 1); } } void Update() { if (tr.position.sqrMagnitude > 25 * 25) { velocity += -tr.position / 25; } tr.position += velocity * Time.deltaTime; } }
Source: https://habr.com/ru/post/182690/
All Articles