
рдХреНрдпрд╛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдШрд╛рд╕-рдлреВрд╕, рдЬрдм рдПрдХ рдмрд╛рд▓реНрдЯреА рдореЗрдВ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдКрдкрд░ рдХреЗ рдЪрд┐рддреНрд░ рдореЗрдВ рдПрдХ рд╕рд░реНрдХрд▓ рдореЗрдВ рдорд╛рд░реНрдЪ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ? рдКрдкрд░ рдХрд╛ рд╕рдЪ
рдШрд╛рд╕ -
рдлреВрд╕ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐
Boids - рдкрдХреНрд╖рд┐рдпреЛрдВ, рдордзреБрдордХреНрдЦрд┐рдпреЛрдВ, рдордЫрд▓рд┐рдпреЛрдВ рдФрд░ рдЕрдиреНрдп рдЬрд╛рдирд╡рд░реЛрдВ рдХреЗ рд╕рд╛рдореВрд╣рд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдПрдХ рдореЙрдбрд▓ рд╣реИред рдореЙрдбрд▓ рдХреА рд╕рд╛рджрдЧреА рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдпрд╣ рдЖрдХрд╕реНрдорд┐рдХ рдЧреБрдгреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ: рдмреЙрдпрдлрд╝ рдПрдХ рдвреЗрд░ рдореЗрдВ рдЗрдХрдЯреНрдард╛ рд╣реЛрддреЗ рд╣реИрдВ, рд╣рд▓рдХреЛрдВ рдореЗрдВ рдЭреБрдВрдб рдореЗрдВ рдЙрдбрд╝рддреЗ рд╣реИрдВ, рд▓реЛрдЧреЛрдВ рдкрд░ рд╣рдорд▓рд╛ рдХрд░рддреЗ рд╣реИрдВред
рдпрд╣ рд▓реЗрдЦ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рд╣реИ, рдЬреЛ рдЕрдиреБрдХреВрд▓рди рдПрдХрддрд╛ рдФрд░ C # рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рд╕рдорд░реНрдкрд┐рдд рд╣реИ, рдЬреЛ
рдкрд╣рд▓реЗ рднрд╛рдЧ рд╕реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рджрд░реНрдЬрдиреЛрдВ рдмрд╛рд░ рдмрдврд╝рд╛рддрд╛ рд╣реИред
рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА
рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рд╣рдо рдХрд╣рд╛рдВ рдЧрдП рдереЗред рдЕрдиреБрдХреВрд▓рди рдХреЗ рдмрд┐рдирд╛ рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рд╕реЗ Boid.csusing 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); } }
рдЖрдЗрдП рдХреБрдЫ рдХреЙрд╕реНрдореЗрдЯрд┐рдХ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░реЗрдВ рдЬреЛ рдЖрдЧреЗ рдХреЗ рдХрд╛рдо рдХреЛ рд╕рд░рд▓ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдХреЛрдб рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ рдХреНрдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХреЗ рдХрд░реАрдм рд▓рд╛рдПрдВрдЧреЗред рд╣рдо рдмреЙрдпрдб рдХреЗ рдореЙрдбрд▓ рдХреЛ рдмрджрд▓ рджреЗрдВрдЧреЗ рддрд╛рдХрд┐ рдпрд╣ рдкрдХреНрд╖реА рдХреА рддрд░рд╣ рджрд┐рдЦреЗ рдФрд░ рд╕рд╛рде рд╣реА рдЗрд╕рдореЗрдВ рдХрдо рддреНрд░рд┐рдХреЛрдг рд╣реЛрдВред рдмреНрд▓реЗрдВрдбрд░ рд╕реЗ рдПрдХ рд╕рд░рд▓ рдкрд┐рд░рд╛рдорд┐рдб рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ред рд╣рдо рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ .blend рдлрд╝рд╛рдЗрд▓ рдХреЛ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдирд┐рд░реАрдХреНрд╖рдХ рдореЗрдВ рдЪреБрдирддреЗ рд╣реИрдВ рдФрд░ рдЖрдпрд╛рдд рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВред рд╣рдо рдкреБрд░рд╛рдиреЗ рдкреНрд░реАрдлрд╝реИрдм рдХреА рдирдХрд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдирдпрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕ рдкрд░ рд╣рдо рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рдЪреВрдВрдХрд┐ рдЕрдм рдкреНрд░реАрдлреИрдм рдХреА рдПрдХ рджрд┐рд╢рд╛ рд╣реИ, рдпрд╣ рдЕрджреНрдпрддрди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд░реЛрдЯреЗрд╢рди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдШреБрдорд╛рдиреЗ рдХреЗ рд▓рд┐рдП
рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо
рд╡реЗрдХреНрдЯрд░ 3 рдХреЛ рд▓реЗ
рдЬрд╛рдПрдВрдЧреЗред рд░реЛрдЯреЗрдЯрдЯрд╛рдЙрдб , рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рд░рд▓ рд╣реИ рдФрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдпрд╣ рдХреЛрдИ рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИред рдкрд╣рд▓реЗ рд╣рдо рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдореЗрдВ рдХреБрдЫ рднреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдлрд┐рд░ рдЖрд╕рд╛рдиреА рд╕реЗ рдШреБрдорд╛рдПрдВред
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;
рд╡реНрдпрд╛рдкрд╛рд░ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рдЙрддрд░ рд░рд╣рд╛ рд╣реИ
рдЪрд▓рд┐рдП рд╢реБрд░реБрдЖрдд рдХрд░рддреЗ рд╣реИрдВ рдХреЗрд▓реЗ рдХреЗ рд╕рд╛рдеред рд╣рдорд╛рд░реЗ рд▓реВрдк рдореЗрдВ, рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдорд┐рдВрдЧ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдорд┐рдВрдЧред рдкреЛрдЬрд╝рд┐рд╢рди - boid.transform.position рддреАрди рдмрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЦрд░рд╛рдм рд╣реИ, рдкрд░рд┐рдгрд╛рдо рдХреЛ рдПрдХ рдЪрд░ рдореЗрдВ рд░рдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рд╕реМ рд╡рд░рджрд╛рдиреЛрдВ рдкрд░, рдпрд╣ рдмрд╛рдд рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдЪрдХреНрд░ рдореЗрдВ рд╣рдЬрд╛рд░ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдкрд░ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдХрдИ рдмрд╛рд░, рдЕрдВрддрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реЛрдЧрд╛ред
var vector = transform.position - boid.transform.position; if (boid != collider && vector.magnitude < separationDistance) { separation += vector / vector.magnitude; separationCount++; }
рдкрд╛рд╕ рдореЗрдВ
рд╡реЗрдХреНрдЯрд░ 3 рд╕реБрдмрд╣ рд╣реИ , рдЬрд┐рд╕реЗ рд╡рд░реНрдЧрдореВрд▓ рдХреА рдЧрдгрдирд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рджреВрд░рд┐рдпреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрд╕реЗ
рд╡реЗрдХреНрдЯрд░ 3.sqrMagnitude рд╕реЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЙрд╕реА рд╕рдордп, рд╣рдо рдПрдХ рднрд╛рд░рд┐рдд рд╡реЗрдХреНрдЯрд░ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рд╕реВрддреНрд░ рдореЗрдВ рдкрд░рд┐рдорд╛рдг рдмрджрд▓рддреЗ рд╣реИрдВ, рдЗрд╕рд╕реЗ рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рд╣реЛрдЧрд╛ред
if (boid != collider && vector.sqrMagnitude < separationDistance * separationDistance) { separation += vector / vector.sqrMagnitude; separationCount++; } тАж if (transform.position.sqrMagnitude > 25 * 25) { velocity += -transform.position.normalized; }
рд░реВрдкрд╛рдВрддрд░рдг рдФрд░ GetComponent
рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ,
рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо рдХреЙрд▓ рдПрдХ рджрд░реНрдЬрди рд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЕрдХреНрд╕рд░ рд▓реВрдк рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдмреЛрд▓рд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╣рдореЗрдВ рдПрдХ рдЙрджрд╛рд╕ рддрд╕реНрд╡реАрд░ рдорд┐рд▓рддреА рд╣реИред рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╡реЗрд╢ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдорд╣рдВрдЧрд╛ рдШрдЯрдХ рдЦреЛрдЬ рдЫреБрдкрд╛рддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ
рдЬрд╛рдЧрдиреЗ рдХреЗ рджреМрд░рд╛рди рдПрдХ рдЕрд▓рдЧ рдЪрд░ рдореЗрдВ рдХреИрд╢ рдХрд░реЗрдВред рдпрд╣ рдШрдЯрдирд╛ рдмреВрдЯ рд╕рдордп рдкрд░ рдЦреЗрд▓ рд╢реБрд░реВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдирд┐рдХрд╛рд▓ рджреА рдЬрд╛рддреА рд╣реИред рдЙрд╕реА рд╕рдордп, рдЖрдк рдХреЙрд▓рдбреНрд░реЙрдк рд╕реЗ тАЛтАЛрдХреЙрд▓ рдХреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЪрд░ рдореЗрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рджреВрд░реА рдХреЗ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ рдХреЙрд▓рд░ рдХреЗ рд╕рд╛рде рд╕реНрдерд┐рддрд┐ рд╕реЗ рддреБрд▓рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
public Transform tr; void Awake() { tr = transform; }
Tr рдХреЗ рд╕рд╛рде рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдХреЙрд▓ рдмрджрд▓реЗрдВред
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++; } }
рд╣рдо рдЖрдЧреЗ рднреА рдЕрдиреБрдХреВрд▓рди рдХрд░реЗрдВрдЧреЗ
рдареАрдХ рд╣реИ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рдбрд╝рдХреЛрдВ рдХреЗ рдмрд╣реБрдд рдХрд░реАрдм рдЖрдиреЗ рдкрд░ рднреА рдПрдлрдкреАрдПрд╕ рдЕрднреА рднреА рдХрдордЬрд╝реЛрд░ рд╣реИред рдФрд░ рд╕рднреА рдХреНрдпреЛрдВрдХрд┐
Physics.OverlapSphere рдХреЛрд▓рд╛рдЗрдбрд░ рдХреА рдмрдврд╝рддреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╣рдо рд╕рднреА boes рдкрд░ рд╕рд░рд▓ рдЧрдгрдирд╛ рдХреЗ рд▓рдЧрднрдЧ рд╕рдорд╛рди рджреНрд╡рд┐рдШрд╛рдд рдЬрдЯрд┐рд▓рддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
рдЗрдВрдЯрд░рдиреЗрдЯ рдХреЗ рдЕрдиреБрд╕рд╛рд░ , рдЭреБрдВрдб рдореЗрдВ рдирд┐рдЧрд▓рдиреЗ рд╡рд╛рд▓реЗ рдХреЗрд╡рд▓ рдЖрдзрд╛ рджрд░реНрдЬрди рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рдмреЙрдпрд▓рд░ рд╕реЗ рднреА рдмрджрддрд░ рдХреНрдпрд╛ рд╣реИ? рд╣рдо рдЪрдХреНрд░ рдХреЛ рдПрдХ рдФрд░ рд╕реНрдерд┐рддрд┐ рддрдХ рд╕реАрдорд┐рдд рдХрд░рддреЗ рд╣реИрдВред рджреЛ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП, рдПрдХ рд▓реВрдк рдмреЗрд╣рддрд░ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рди рдХреЗрд╡рд▓ рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреА рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдиреНрдпреВрдирддрдо рднреА рд╣реИред рдкрд╛рд╕ рдореЗрдВ рдХреЛрдИ рдкрдбрд╝реЛрд╕реА рди рд╣реЛрдиреЗ рдкрд░ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреА рд╕реНрдерд┐рддрд┐ рдЬреЛрдбрд╝реЗрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд╡реИрдХреНрдЯрд░ рдХреА рдЧрдгрдирд╛ рдореЗрдВ рднрд╛рдЬрдХ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛, рдЕрдиреНрдпрдерд╛, рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреА рдПрдХ рдмрдбрд╝реА рднреАрдбрд╝ рдХреЗ рд╕рд╛рде, рдмреЙрдпрдбреНрд╕ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХрд╛ рдореМрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛ред
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);
рдЕрдм рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рд╡реЗрдЧ рд╡реЗрдХреНрдЯрд░ рдХреЛ рднреА рдЕрдХреНрд╕рд░ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрд╕реНрдкреЗрдХреНрдЯрд░ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдПрдХ рдХрджрдо рдЙрдард╛рдПрдВ рдФрд░ рдЪреАрдЬреЛрдВ рдХреЛ рдбрд╛рд▓реЗрдВред рдЖрдЗрдП рд╕рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЪрд░ рдХреЛ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП
HideInInspector рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдХреБрдЫ рдирдП рдЬреЛрдбрд╝реЗред рдЯрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝реЗрдВ, рдЗрд╕реЗ рдЯрд╛рдЗрдорд░ рджреНрд╡рд╛рд░рд╛ рдХреЙрд▓рд░ рдореЗрдВ рд╕реНрдерд╛рди рджреЗрдВред
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);
рдЕрдЧрд▓рд╛, рдЕрдкрдиреЗ рдХрд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд┐рдВрдЯ рдХрд░реЗрдВ рдФрд░ рддрд╛рдЬрд╝рд╛ рджрд░ рдХреЛ 2 рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░реЗрдВред рд╣рд╛рдБ, рд╣рд╛рдБ, рдЖрдкрдиреЗ рд╕рд╣реА рд╕реБрдирд╛, рд╣рдорд╛рд░реЗ рдореБрдХрд╛рдмрд▓реЗ рдмреАрд╕ рдЧреБрдирд╛ рдХрдоред рдЙрд╕реА рд╕рдордп, рд╣рдо рдХрд╛рд░рдХреЛрдВ рдХреЛ рд╕рд╣реА рдХрд░реЗрдВрдЧреЗред рдЕрдм, рд╕реИрдХрдбрд╝реЛрдВ boids рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдПрдХ рд╣рдЬрд╛рд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдиреБрдХреВрд▓рд┐рдд, рдЕрдиреБрдХреВрд▓рд┐рдд, рд▓реЗрдХрд┐рди рдЕрдиреБрдХреВрд▓рд┐рдд рдирд╣реАрдВ
рдирдИ рд╕рдорд╕реНрдпрд╛ред рдПрдХ рдмрд╛рд░ рд╣рд░ рджреЛ рд╕реЗрдХрдВрдб рдореЗрдВ, рд╕рднреА рдмреЙрдпрдбреНрд╕ рдирдП рд╡реИрдХреНрдЯрд░ рдХреА рдЧрдгрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд▓рд╣рд░ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред рдкреНрд░рднрд╛рд╡, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ, рд▓реЗрдХрд┐рди рдкрдХреНрд╖рд┐рдпреЛрдВ рдХреЛ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдХреИрд╕реЗред рд╣рдо рдПрдХ рдФрд░ рд╕рд░рд▓ рдЕрдиреБрдХреВрд▓рди рдХрд░рддреЗ рд╣реИрдВ - рд╣рдо
рд░реИрдВрдбрдо.рд╡рд▓реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдордп рдореЗрдВ рдЧрдгрдирд╛ рд╡рд┐рддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
InvokeRepeating("CalculateVelocity", Random.value * tick, tick);
рдареАрдХ рд╣реИ, рддрд╛рдХрд┐ рдЕрдиреБрдХрд░рдг рдХреА рд╢реБрд░реБрдЖрдд рдмрд╣реБрдд рдЕрдЬреАрдм рди рд▓рдЧреЗ, рдЬрд╛рдЧрдиреЗ рдореЗрдВ рд╣рдо random.onUnitSphere рд╕реЗ рдпрд╛рджреГрдЪреНрдЫрд┐рдХрддрд╛ рдХрд╛ рдПрдХ рддрддреНрд╡ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
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);
FPS рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЖрдк
рднреМрддрд┐рдХреА рдкреНрд░рдмрдВрдзрдХ рдореЗрдВ рдПрдХ рдиреНрдпреВрдирддрдо рдкрд░
рд╕реЙрд▓реНрд╡рд░ Iteration рдЧрдгрдирд╛ рдХреЛ
рд╣рдЯрд╛ рджрд┐рдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк
рдЯрд╛рдЗрдо рдореИрдиреЗрдЬрд░ рдореЗрдВ рдлрд┐рдХреНрд╕реНрдб рдЯрд╛рдЗрдорд╕реНрдЯреЗрдк рдФрд░ рдЕрдзрд┐рдХрддрдо рдЕрдиреБрдорддрд┐ рдкреНрд░рд╛рдкреНрдд рдЯрд╛рдЗрдорд╕реНрдЯреЗрдк рдХреЗ рд╕рд╛рде рдЦреЗрд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреВрд░ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕рд┐рдореБрд▓реЗрд╢рди рдЕрд░рд╛рдЬрдХ рдФрд░ рдмрджрд╕реВрд░рдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
рдПрдХ рдФрд░ рдЕрддрд┐ рд╕реВрдХреНрд╖реНрдо рдЕрдВрддрд░ рд░реЛрдЯреЗрд╢рди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИред рдЬрдм рд╣рдо рдореЙрдбрд▓ рдХреЛ рдШреБрдорд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЙрд╕рд╕реЗ рдЬреБрдбрд╝реЗ рдЧреЛрд▓рд╛рдХрд╛рд░ рдХреЛрд▓рд╛рдЗрдбрд░ рдХреЛ рдШреБрдорд╛рддреЗ рд╣реИрдВред рдорд╣рдВрдЧрд╛ рдФрд░ рдмреЗрдХрд╛рд░ред рдореЙрдбрд▓ рдХреЛ рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рдХреЛрд▓рд╛рдЗрдбрд░ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдХреЗ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддреЛ рдЖрдк рдПрдХ рдФрд░ рдкрд╛рдВрдЪ рдПрдлрдкреАрдПрд╕ рдЬреАрдд рд╕рдХрддреЗ рд╣реИрдВред
public Transform model; тАж if (velocity != Vector3.zero && model.forward != velocity.normalized) { model.forward = Vector3.RotateTowards(model.forward, velocity, turnSpeed, 1); }
рдирд┐рд╖реНрдХрд░реНрд╖
рд╡рд╣ рд╕рдм рд╣реИред рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдмрдбрд╝рд╛ рд╣рд┐рд╕реНрд╕рд╛ рдлреНрд░реЗрдо рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рд▓реЗ рдЬрд╛рдХрд░ рдФрд░ рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреЛ рдЦреЛрдЬрдХрд░ рдЦрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд╣рд▓реЗ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рджреВрд╕рд░реЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рднреМрддрд┐рдХреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрдВрдж рдХрд░рдиреЗ рдФрд░ рдЗрд╕реЗ рдореБрд╢реНрдХрд┐рд▓ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╖рдп рд╣реИред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рдордЭрджрд╛рд░ рдлреЗрд░реАрд╡рд╛рд▓реЗ рддреЗрдЬреА рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рдкреЗрд╢рдХрд╢ рдХрд░реЗрдВрдЧреЗред
Boid.cs рдХрд╛ рдЕрдиреБрдХреВрд▓рд┐рдд рд╕рдВрд╕реНрдХрд░рдг 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; } }
рдЧрд┐рдЯрд╣рдм рдкрд░ рд╕реВрддреНрд░ |
рдПрдХрддрд╛ рд╡реЗрдм рдкреНрд▓реЗрдпрд░ рдХреЗ рдорд╛рд▓рд┐рдХреЛрдВ рдХреЗ рд▓рд┐рдП рдСрдирд▓рд╛рдЗрди рд╕рдВрд╕реНрдХрд░рдг