rename fov vars, add documentation & better comements to BoidController class, fix BoidControllerEditor redraw and implement circle/arc vertex/width attributes (no serialization with static class)

This commit is contained in:
Xevion
2020-06-06 01:17:19 -05:00
parent 7e561c7ea2
commit f5bfa7ace8
4 changed files with 67 additions and 39 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
/// <summary>
/// Utility function for setting up Camera and Boundary related variables.
/// </summary>
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);
}
/// <summary>
/// Adds a number of boids.
/// </summary>
/// <param name="n"></param>
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 {
}
}
/// <summary>
/// Removes a number of boids.
/// </summary>
/// <param name="n">Number of Boids to Remove</param>
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 {
}
}
/// <summary>
/// Remove a Boid at a specific index in the Boids array.
/// </summary>
/// <param name="index"></param>
private void RemoveBoid(int index) {
Boid boid = boids[index];
boids.RemoveAt(index);
Destroy(boid.transform.gameObject);
}
/// <summary>
/// Returns a random valid Boid position
/// </summary>
/// <returns>A Vector2 position within the Boid boundary area</returns>
private Vector2 RandomPosition() {
return new Vector2(
Random.Range(-Boundary.size.x, Boundary.size.x) / 2,

View File

@@ -4,12 +4,14 @@
/// A simple static utility class that assists with drawing shapes using the <c>LineRenderer</c> class.
/// </summary>
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;
/// <summary>
/// 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 <c>angle</c> degrees.