diff --git a/Boids/Assets/Editor/BoidControllerEditor.cs b/Boids/Assets/Editor/BoidControllerEditor.cs
index eb2050f..2e4b6ed 100644
--- a/Boids/Assets/Editor/BoidControllerEditor.cs
+++ b/Boids/Assets/Editor/BoidControllerEditor.cs
@@ -9,7 +9,7 @@ public class BoidControllerEditor : UnityEditor.Editor {
// Boid Count update
EditorGUI.BeginChangeCheck();
- controller.boidCount = EditorGUILayout.IntSlider("Boid Count", controller.boidCount, 1, 500);
+ controller.boidCount = EditorGUILayout.IntSlider("Boid Count", controller.boidCount, -1, 500);
// Check must be performed or Boids will be added outside of gameplay
if (EditorGUI.EndChangeCheck() && Application.isPlaying) {
int diff = controller.boidCount - controller.boids.Count;
@@ -32,7 +32,7 @@ public class BoidControllerEditor : UnityEditor.Editor {
controller.boidGroupRange = EditorGUILayout.Slider("Group Range", controller.boidGroupRange, 0.01f, 7.5f);
controller.boidSeparationRange =
EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f);
- controller.boidFOV = EditorGUILayout.Slider("Boid FOV", controller.boidFOV, 1f, 360f);
+ controller.boidFov = EditorGUILayout.Slider("Boid FOV", controller.boidFov, 1f, 360f);
redraw = redraw || EditorGUI.EndChangeCheck();
// Boid Bias Attributes
@@ -47,20 +47,24 @@ public class BoidControllerEditor : UnityEditor.Editor {
controller.enableAlignment = EditorGUILayout.Toggle("Enable Alignment?", controller.enableAlignment);
controller.enableCohesion = EditorGUILayout.Toggle("Enable Cohesion?", controller.enableCohesion);
controller.enableSeparation = EditorGUILayout.Toggle("Enable Separation?", controller.enableSeparation);
- controller.enableBoundary = EditorGUILayout.Toggle("Enable Boundary?", controller.enableBoundary);
- controller.enableFOVChecks = EditorGUILayout.Toggle("Enable FOV?", controller.enableFOVChecks);
-
- // Boid Rendering
+
+ // Relevant to Focused Boid Rendering
EditorGUI.BeginChangeCheck();
- controller.circleVertexCount =
- EditorGUILayout.IntSlider("Circle Vertex Count", controller.circleVertexCount, 4, 360);
- // controller.arcVertexCount =
- // EditorGUILayout.IntSlider("Arc Vertex Count", controller.arcVertexCount, -1, 360);
- controller.circleWidth = EditorGUILayout.Slider("Circle Line Width", controller.circleWidth, 0.01f, 1f);
+ controller.enableFovChecks = EditorGUILayout.Toggle("Enable FOV?", controller.enableFovChecks);
+ redraw = redraw || EditorGUI.EndChangeCheck();
+
+ controller.enableBoundary = EditorGUILayout.Toggle("Enable Boundary?", controller.enableBoundary);
+
+ // Focused Boid Rendering Attributes
+ EditorGUI.BeginChangeCheck();
+ ShapeDraw.CircleVertexCount = EditorGUILayout.IntSlider("Circle Vertex Count", ShapeDraw.CircleVertexCount, 4, 360);
+ ShapeDraw.ArcVertexCount = EditorGUILayout.IntSlider("Arc Vertex Count", ShapeDraw.ArcVertexCount + 2, 3, 360) - 2;
+ ShapeDraw.CircleWidth = EditorGUILayout.Slider("Circle Line Width", ShapeDraw.CircleWidth, 0.01f, 1f);
+ ShapeDraw.ArcWidth = EditorGUILayout.Slider("Arc Line Width", ShapeDraw.ArcWidth, 0.01f, 1f);
redraw = redraw || EditorGUI.EndChangeCheck();
// Inspector elements related to Boid Focusing have changed - redraw!
- if (redraw)
+ if (redraw && controller.focusedBoid != null)
controller.focusedBoid.Draw(true);
}
}
\ No newline at end of file
diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs
index 20c4082..7fe24f1 100644
--- a/Boids/Assets/Scripts/Boid.cs
+++ b/Boids/Assets/Scripts/Boid.cs
@@ -180,12 +180,12 @@ public class Boid : MonoBehaviour {
continue;
// FOV Check
- if (_parent.enableFOVChecks) {
+ if (_parent.enableFovChecks) {
float angle1 = Util.Vector2ToAngle(_velocity); // Current Heading
float angle2 = Util.AngleBetween(transform.position, boid.transform.position); // Angle between Boid and other Boid
// Outside of FOV range, skip
- if (Mathf.Abs(Mathf.DeltaAngle(angle1, angle2)) > _parent.boidFOV / 2)
+ if (Mathf.Abs(Mathf.DeltaAngle(angle1, angle2)) > _parent.boidFov / 2)
continue;
}
@@ -258,16 +258,16 @@ public class Boid : MonoBehaviour {
lineRenderer.positionCount = 0;
// Add a LineRenderer for Radius Drawing
- if(_parent.enableFOVChecks)
- ShapeDraw.DrawArc(_lineRenderers[2], _parent.boidFOV, _parent.boidGroupRange); // FOV Arc
+ if(_parent.enableFovChecks)
+ ShapeDraw.DrawArc(_lineRenderers[2], _parent.boidFov, _parent.boidGroupRange); // FOV Arc
else
ShapeDraw.DrawCircle(_lineRenderers[0], _parent.boidGroupRange); // Group Circle
ShapeDraw.DrawCircle(_lineRenderers[1], _parent.boidSeparationRange); // Separation Circle
- if (_parent.enableFOVChecks) {
+ if (_parent.enableFovChecks) {
// Set FOV Arc rotation to mimic Boid transform rotation
_lineRenderers[2].transform.rotation = transform.rotation;
- _lineRenderers[2].transform.Rotate(0, 0, _parent.boidFOV / 2f);
+ _lineRenderers[2].transform.Rotate(0, 0, _parent.boidFov / 2f);
}
}
}
\ No newline at end of file
diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs
index 1b7b711..5b0a320 100644
--- a/Boids/Assets/Scripts/BoidController.cs
+++ b/Boids/Assets/Scripts/BoidController.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
+using Debug = System.Diagnostics.Debug;
using Random = UnityEngine.Random;
public class BoidController : MonoBehaviour {
@@ -28,17 +29,17 @@ public class BoidController : MonoBehaviour {
[SerializeField] public bool enableAlignment = true;
[SerializeField] public bool enableCohesion = true;
[SerializeField] public bool enableBoundary = true;
- [SerializeField] public bool enableFOVChecks = true;
+ [SerializeField] public bool enableFovChecks = true;
[SerializeField] public float boidSeparationRange = 2.3f; // Boid Separation rule's activation distance
[SerializeField] public float boundaryForce = 10f; // The force applied when a Boid hits the boundary
[SerializeField] public bool localFlocks = true; // Calculate Local 'Neighborhood' for flocks?
[SerializeField] public bool edgeWrapping = true; // Enforce Edge Wrapping
[SerializeField] public int circleVertexCount = 360; // The number of vertices for circles displayed
- [SerializeField] public int arcVertexCount = -1; // The number of vertices for arcs displayed, -1 for auto
+ [SerializeField] public int arcVertexCount = 180; // The number of vertices for arcs displayed, -1 for auto
[SerializeField] public float circleWidth = 0.1f; // Width of circle
[SerializeField] public float maxSteerForce = 10f;
- [SerializeField] public float boidFOV = 160;
+ [SerializeField] public float boidFov = 220;
public Boid focusedBoid; // A focused Boid has special rendering
@@ -51,11 +52,6 @@ public class BoidController : MonoBehaviour {
Gizmos.DrawWireCube(Space.center, Space.size);
Gizmos.DrawWireCube(Boundary.center, Boundary.size);
-#if UNITY_EDITOR
- if (focusedBoid != null)
- Handles.DrawWireDisc(focusedBoid.transform.position, Vector3.forward, boidGroupRange);
-#endif
-
if (Cam == null)
return;
@@ -75,6 +71,7 @@ public class BoidController : MonoBehaviour {
if (focusedBoid != null)
focusedBoid.DisableFocusing();
+ // Pick a Boid randomly and enable focusing
focusedBoid = boids[Random.Range(0, boids.Count)];
focusedBoid.EnableFocusing();
}
@@ -87,25 +84,37 @@ public class BoidController : MonoBehaviour {
}
private void Start() {
+ SetupCamera();
+ AddBoids(boidCount);
+ }
+
+ ///
+ /// Utility function for setting up Camera and Boundary related variables.
+ ///
+ private void SetupCamera() {
// Setup Camera
Cam = Camera.main;
+ // Assert that there is an active camera
+ Debug.Assert(Cam != null, nameof(Cam) + " != null");
+
// Size the Rectangle based on the Camera's Orthographic View
float height = 2f * Cam.orthographicSize;
var size = new Vector2(height * Cam.aspect, height);
Space = new Rect((Vector2) transform.position - size / 2, size);
Boundary = new Rect(Vector2.zero, Space.size * 0.95f);
Boundary.center = Space.center;
-
- ShapeDraw.CircleWidth = circleWidth;
- ShapeDraw.ArcWidth = circleWidth;
- ShapeDraw.CircleVertexCount = circleVertexCount;
- // ShapeDraw.ArcVertexCount = arcVertexCount;
-
- AddBoids(boidCount);
}
+ ///
+ /// Adds a number of boids.
+ ///
+ ///
public void AddBoids(int n) {
+ // Skip if negative or zero
+ if (n <= 0)
+ return;
+
for (int i = 0; i < n; i++) {
// Instantiate a Boid prefab within the boundaries randomly
Vector2 position = RandomPosition() * 0.95f;
@@ -117,7 +126,12 @@ public class BoidController : MonoBehaviour {
}
}
+ ///
+ /// Removes a number of boids.
+ ///
+ /// Number of Boids to Remove
public void RemoveBoids(int n) {
+ // If there are still Boids to remove and the number left to remove is more than 1 (post-decrementing)
while (n-- > 0 && boids.Count >= 1) {
int index = Random.Range(0, boids.Count - 1);
@@ -132,12 +146,20 @@ public class BoidController : MonoBehaviour {
}
}
+ ///
+ /// Remove a Boid at a specific index in the Boids array.
+ ///
+ ///
private void RemoveBoid(int index) {
Boid boid = boids[index];
boids.RemoveAt(index);
Destroy(boid.transform.gameObject);
}
+ ///
+ /// Returns a random valid Boid position
+ ///
+ /// A Vector2 position within the Boid boundary area
private Vector2 RandomPosition() {
return new Vector2(
Random.Range(-Boundary.size.x, Boundary.size.x) / 2,
diff --git a/Boids/Assets/Scripts/ShapeDraw.cs b/Boids/Assets/Scripts/ShapeDraw.cs
index 9707b03..77bd48c 100644
--- a/Boids/Assets/Scripts/ShapeDraw.cs
+++ b/Boids/Assets/Scripts/ShapeDraw.cs
@@ -4,12 +4,14 @@
/// A simple static utility class that assists with drawing shapes using the LineRenderer class.
///
public static class ShapeDraw {
- public static float CircleWidth = 1f;
- public static float ArcWidth = 1f;
- public static int CircleVertexCount = 360;
- public static int ArcVertexCount = 77;
-
-
+ // Line width of the Circle and Arc
+ public static float CircleWidth = 0.1f;
+ public static float ArcWidth = 0.1f;
+ // Vertex count for Circle and Arc - the precision or detail level the curves have
+ // Low vertex counts are mostly unnoticeable until < 30 vertexes, where eventually squares and triangles appear
+ public static int CircleVertexCount = 180;
+ public static int ArcVertexCount = 90;
+
///
/// Draw a Arc aimed straight up with a certain angle width and radius.
/// This Arc is not direct at any specific angle and start from 0 degrees and ends at angle degrees.