AdjustmentsHandler AddBoids useNearby check, move all rules into GetVelocity method to try pre simulating new boids (failed), Wrapping docs, buggy GetClosestBoid, new TimeScale slider!

This commit is contained in:
Xevion
2020-06-06 07:12:59 -05:00
parent 0a44ee58ed
commit fe79a5ff5e
4 changed files with 91 additions and 37 deletions

View File

@@ -64,5 +64,7 @@ public class BoidControllerEditor : UnityEditor.Editor {
// Inspector elements related to Boid Focusing have changed - redraw!
if (redraw && controller.focusedBoid != null)
controller.focusedBoid.Draw(true);
Time.timeScale = EditorGUILayout.Slider("Time Scale", Time.timeScale, 0.02f, 1f);
}
}

View File

@@ -81,7 +81,7 @@ public class AdjustmentsHandler : MonoBehaviour {
// Calculate diff, formally add/remove boids
int diff = controller.boidCount - controller.boids.Count;
if(diff > 0)
controller.AddBoids(diff);
controller.AddBoids(diff, controller.boidCount > 5);
else if(diff < 0)
controller.RemoveBoids(diff * -1);

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Boid : MonoBehaviour {
@@ -24,8 +25,7 @@ public class Boid : MonoBehaviour {
private void Start() {
_parent = transform.parent
.GetComponent<BoidController>(); // Parent used to perform physics math without caching
velocity = Util.GetRandomVelocity(Random.Range(_parent.minSpeed,
_parent.maxSpeed)); // Acquire a Velocity Vector with a magnitude
velocity = Util.GetRandomVelocity(Random.Range(_parent.minSpeed, _parent.maxSpeed));
_position = transform.position; // Track 2D position separately
transform.name = $"Boid {transform.GetSiblingIndex()}"; // Name the Game Object so Boids can be tracked somewhat
}
@@ -41,45 +41,58 @@ public class Boid : MonoBehaviour {
transform.position = _position;
}
else {
// Find local neighborhood flock
Vector2 acceleration = Vector2.zero;
List<Boid> flock = _parent.localFlocks ? GetFlock(_parent.boids, _parent.boidGroupRange) : _parent.boids;
latestNeighborhoodCount = flock.Count;
// Only update latest neighborhood when we need it for focused boid Gizmo draws
if (isFocused)
latestNeighborhood = flock;
// Calculate all offsets and multiple by magnitudes given
if (flock.Count > 0) {
if (_parent.enableCohesion)
acceleration += SteerTowards(Rule1(flock)) * _parent.cohesionBias;
if (_parent.enableSeparation)
acceleration += SteerTowards(Rule2(flock)) * _parent.separationBias;
if (_parent.enableAlignment)
acceleration += SteerTowards(Rule3(flock)) * _parent.alignmentBias;
}
if (_parent.enableBoundary && !_parent.Boundary.Contains(_position)) {
acceleration += SteerTowards(RuleBound()) * _parent.boundaryBias;
}
// Limit the Velocity Vector to a certain Magnitude
velocity += acceleration * Time.deltaTime;
float speed = velocity.magnitude;
Vector2 dir = velocity / speed;
speed = Mathf.Clamp(speed, _parent.minSpeed, _parent.maxSpeed);
velocity = dir * speed;
velocity = GetVelocity();
_position += velocity * Time.deltaTime;
transform.position = _position;
// transform.forward = dir;
}
// Perform edge wrapping
if (_parent.edgeWrapping)
Wrapping();
}
/// <summary>
/// Gets Velocity used to move Boid with all current rules and velocity
/// </summary>
/// <returns>new current Vector2 velocity</returns>
public Vector2 GetVelocity() {
// Find local neighborhood flock
Vector2 acceleration = Vector2.zero;
List<Boid> flock;
if (_parent.localFlocks)
flock = GetFlock(_parent.boids, _parent.boidGroupRange);
else
flock = _parent.boids;
latestNeighborhoodCount = flock.Count;
// Only update latest neighborhood when we need it for focused boid Gizmo draws
if (isFocused)
latestNeighborhood = flock;
// Calculate all offsets and multiple by magnitudes given
if (flock.Count > 0) {
if (_parent.enableCohesion)
acceleration += SteerTowards(Rule1(flock)) * _parent.cohesionBias;
if (_parent.enableSeparation)
acceleration += SteerTowards(Rule2(flock)) * _parent.separationBias;
if (_parent.enableAlignment)
acceleration += SteerTowards(Rule3(flock)) * _parent.alignmentBias;
}
if (_parent.enableBoundary && !_parent.Boundary.Contains(_position)) {
acceleration += SteerTowards(RuleBound()) * _parent.boundaryBias;
}
// Limit the Velocity Vector to a certain Magnitude
Vector2 newVelocity = velocity + acceleration * Time.deltaTime;
float speed = newVelocity.magnitude;
Vector2 dir = newVelocity / speed;
speed = Mathf.Clamp(speed, _parent.minSpeed, _parent.maxSpeed);
return dir * speed;
}
/// <summary>
/// Assists with clamping and normalizing a Vector2 force
/// </summary>
@@ -90,6 +103,9 @@ public class Boid : MonoBehaviour {
return Vector2.ClampMagnitude(v, _parent.maxSteerForce);
}
/// <summary>
/// Runs edge wrapping logic for detecting and wrapping Boids
/// </summary>
private void Wrapping() {
if (!_parent.Space.Contains(_position)) {
// Activate Wrap, Move
@@ -295,4 +311,26 @@ public class Boid : MonoBehaviour {
return _position + Util.RotateBy(new Vector2(distance, distance),
Random.Range(0f, 360f));
}
public Boid GetClosestBoid() {
if (_parent.boids.Count <= 1)
return null;
Boid best = _parent.boids[0];
float curDistSqr = Mathf.Infinity;
foreach (Boid potential in _parent.boids) {
if (potential == this)
continue;
Vector2 diff = potential._position - _position;
var diffSqrMag = diff.sqrMagnitude;
if (diffSqrMag < curDistSqr) {
curDistSqr = diffSqrMag;
best = potential;
}
}
return best;
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
@@ -82,6 +83,17 @@ public class BoidController : MonoBehaviour {
private void Start() {
SetupCamera();
AddBoids(boidCount);
StartCoroutine(LateStart());
}
private IEnumerator LateStart() {
yield return new WaitForSecondsRealtime(0.5f);
for (int i = 0; i < 100; i++) {
foreach (Boid boid in boids)
boid.velocity = boid.GetVelocity();
}
}
/// <summary>
@@ -115,11 +127,13 @@ public class BoidController : MonoBehaviour {
for (int i = 0; i < n; i++) {
// Instantiate a Boid prefab within the boundaries randomly
Vector2 position = useNearby ? RandomNearbyPosition() : RandomPosition() * 0.90f;
GameObject boid = Instantiate(boidObject, position, Quaternion.identity);
GameObject boidGO = Instantiate(boidObject, position, Quaternion.identity);
// Set parent, add Boid component to Boids list
boid.transform.parent = transform;
boids.Add(boid.GetComponent<Boid>());
boidGO.transform.parent = transform;
var boid = boidGO.GetComponent<Boid>();
boids.Add(boid);
}
}