From 74ddf684a98b4c770590d06f50225348425fee73 Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 27 May 2020 10:45:41 -0500 Subject: [PATCH 01/19] implemented FOV checks, back to foreach loop, BoidController sliders --- Boids/Assets/Scripts/Boid.cs | 18 +++++++++++++++++- Boids/Assets/Scripts/BoidController.cs | 2 ++ Boids/Assets/Scripts/BoidControllerEditor.cs | 8 +++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index d31ece5..4d248aa 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -169,7 +169,23 @@ public class Boid : MonoBehaviour { // Returns a list of boids within a certain radius of the Boid, representing it's local 'flock' private List GetFlock(List boids, float radius) { - return boids.Where(boid => boid != this && Vector2.Distance(this._position, boid._position) <= radius).ToList(); + List flock = new List(); + + foreach (Boid boid in boids) { + if (boid == this || Vector2.Distance(this._position, boid._position) > radius) + continue; + + if (_parent.enableFOVChecks) { + float angle1 = Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y); + float angle2 = Mathf.Rad2Deg * -Mathf.Atan2(boid._velocity.x, boid._velocity.y); + if (Mathf.Abs(angle2 - angle1) > _parent.boidFOV / 2) + continue; + } + + flock.Add(boid); + } + + return flock; } // Sets up a Boid to be 'Focused', adds Circles around object and changes color diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index 211cfc5..f2cbea2 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -29,6 +29,7 @@ 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 float boidSeparationRange = 2.3f; // Boid Separation rule's activation distance [SerializeField] public float boundaryForce = 10f; // The force applied when a Boid hits the boundary @@ -37,6 +38,7 @@ public class BoidController : MonoBehaviour { [SerializeField] public int circleVertexCount = 40; // The number of vertices for circles displayed [SerializeField] public float circleWidth = 0.1f; // Width of circle [SerializeField] public float maxSteerForce = 10f; + [SerializeField] public float boidFOV = 160; public Boid focusedBoid; // A focused Boid has special rendering diff --git a/Boids/Assets/Scripts/BoidControllerEditor.cs b/Boids/Assets/Scripts/BoidControllerEditor.cs index 1ff1fbf..112dfe5 100644 --- a/Boids/Assets/Scripts/BoidControllerEditor.cs +++ b/Boids/Assets/Scripts/BoidControllerEditor.cs @@ -26,12 +26,13 @@ public class BoidControllerEditor : Editor { controller.maxSpeed = EditorGUILayout.Slider("Maximum Speed", controller.maxSpeed, 0.01f, 25.0f); controller.boidSeparationRange = EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f); controller.boundaryForce = EditorGUILayout.Slider("Boundary Force", controller.boundaryForce, 0.25f, 50f); - controller.maxSteerForce = EditorGUILayout.Slider("Max Steer Force", controller.maxSteerForce, 1f, 200f); - + controller.maxSteerForce = EditorGUILayout.Slider("Max Steer Force", controller.maxSteerForce, 1f, 500f); + controller.boidFOV = EditorGUILayout.Slider("Boid FOV", controller.boidFOV, 1f, 360f); + // Boid Bias Attributes controller.alignmentBias = EditorGUILayout.Slider("Alignment Bias", controller.alignmentBias, 0.001f, 1.5f); controller.cohesionBias = EditorGUILayout.Slider("Cohesion Bias", controller.cohesionBias, 0.001f, 1.5f); - controller.separationBias = EditorGUILayout.Slider("Separation Bias", controller.separationBias, 0.001f, 1.5f); + controller.separationBias = EditorGUILayout.Slider("Separation Bias", controller.separationBias, 0.001f, 2.5f); controller.boundaryBias = EditorGUILayout.Slider("Boundary Bias", controller.boundaryBias, 0.01f, 1.5f); controller.localFlocks = EditorGUILayout.Toggle("Use Groups?", controller.localFlocks); @@ -41,6 +42,7 @@ public class BoidControllerEditor : Editor { 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 controller.circleVertexCount = EditorGUILayout.IntSlider("Circle Vertex Count", controller.circleVertexCount, 4, 360); From 784d498a529b735f224892089f340e512339ff1f Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 27 May 2020 19:18:05 -0500 Subject: [PATCH 02/19] neighbor count label gizmo, attempt at arc FOV gizmo, make min/max speed sliders into single min/max slider --- Boids/Assets/Scenes/Project.unity | 24 ++++++++-------- Boids/Assets/Scripts/Boid.cs | 29 ++++++++++++++++---- Boids/Assets/Scripts/BoidController.cs | 1 - Boids/Assets/Scripts/BoidControllerEditor.cs | 5 ++-- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/Boids/Assets/Scenes/Project.unity b/Boids/Assets/Scenes/Project.unity index 16309aa..453310c 100644 --- a/Boids/Assets/Scenes/Project.unity +++ b/Boids/Assets/Scenes/Project.unity @@ -1252,27 +1252,29 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 7d72224fef7a4fb4a998b0980fe0eb77, type: 3} m_Name: m_EditorClassIdentifier: - boidCount: 372 - boidGroupRange: 3.03 + boidCount: 244 + boidGroupRange: 3.29 boidStartVelocity: 14.8 - minSpeed: 12 - maxSpeed: 12 + minSpeed: 9.225757 + maxSpeed: 9.225757 globalBias: 1 - separationBias: 1.5 - alignmentBias: 0.517 - cohesionBias: 0.451 - boundaryBias: 1.492 + separationBias: 1.95 + alignmentBias: 0.288 + cohesionBias: 0.296 + boundaryBias: 1.5 enableSeparation: 1 enableAlignment: 1 enableCohesion: 1 enableBoundary: 1 - boidSeparationRange: 2.3 - boundaryForce: 7.6 + enableFOVChecks: 1 + boidSeparationRange: 1.4 + boundaryForce: 50 localFlocks: 1 edgeWrapping: 1 circleVertexCount: 360 circleWidth: 0.1 - maxSteerForce: 138 + maxSteerForce: 383 + boidFOV: 297 focusedBoid: {fileID: 0} boidObject: {fileID: 1737515784064720040, guid: 23e1eaaf69d4ef342ac3ef9590f6c642, type: 3} diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 4d248aa..5e0cefc 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; +using UnityEditor; using UnityEngine; -using Random = UnityEngine.Random; // Boids are represented by a moving, rotating triangle. // Boids should communicate with sibling Boids @@ -29,7 +27,7 @@ public class Boid : MonoBehaviour { private void Update() { // Updates the rotation of the object based on the Velocity - transform.rotation = Quaternion.Euler(0, 0, Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y)); + transform.eulerAngles = new Vector3(0, 0, Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y)); // Skip Flock Calculations if wrapping in progress if (_isWrappingX || _isWrappingY) { @@ -71,6 +69,27 @@ public class Boid : MonoBehaviour { Wrapping(); } + private void OnDrawGizmos() { + // Show # of Boids in Neighborhood + Handles.Label(transform.position, $"{_latestNeighborhoodCount}"); + + // Draw a Wire Arc visualizing FOV + if (isFocused) { + float angle = transform.eulerAngles.z + (_parent.boidFOV / 2f); + Vector3 from = Quaternion.AngleAxis(angle, Vector3.up) * Vector3.forward; + Handles.DrawWireArc(transform.position, transform.forward, from, _parent.boidFOV, + (_parent.boidGroupRange + _parent.boidSeparationRange) / 2f); + } + } + + public Vector3 DirectionFromAngle(float _angleInDeg, bool _global) { + if (_global == false) { + _angleInDeg += transform.eulerAngles.z; + } + + return new Vector3(Mathf.Sin(_angleInDeg * Mathf.Deg2Rad), Mathf.Cos(_angleInDeg * Mathf.Deg2Rad), 0); + } + private Vector2 SteerTowards(Vector2 vector) { Vector2 v = vector.normalized * _parent.maxSpeed - _velocity; return Vector2.ClampMagnitude(v, _parent.maxSteerForce); @@ -170,7 +189,7 @@ public class Boid : MonoBehaviour { // Returns a list of boids within a certain radius of the Boid, representing it's local 'flock' private List GetFlock(List boids, float radius) { List flock = new List(); - + foreach (Boid boid in boids) { if (boid == this || Vector2.Distance(this._position, boid._position) > radius) continue; diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index f2cbea2..0b5efcf 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using UnityEditor; using UnityEngine; -using Debug = System.Diagnostics.Debug; using Random = UnityEngine.Random; public class BoidController : MonoBehaviour { diff --git a/Boids/Assets/Scripts/BoidControllerEditor.cs b/Boids/Assets/Scripts/BoidControllerEditor.cs index 112dfe5..644773b 100644 --- a/Boids/Assets/Scripts/BoidControllerEditor.cs +++ b/Boids/Assets/Scripts/BoidControllerEditor.cs @@ -22,8 +22,9 @@ public class BoidControllerEditor : Editor { // Basic Boid Controller Attributes controller.boidGroupRange = EditorGUILayout.Slider("Group Range", controller.boidGroupRange, 0.01f, 7.5f); controller.boidStartVelocity = EditorGUILayout.Slider("Start Velocity", controller.boidStartVelocity, 0.01f, 25.0f); - controller.minSpeed = EditorGUILayout.Slider("Minimum Speed", controller.minSpeed, 0.01f, 25.0f); - controller.maxSpeed = EditorGUILayout.Slider("Maximum Speed", controller.maxSpeed, 0.01f, 25.0f); + EditorGUILayout.MinMaxSlider("Speed Limit", ref controller.minSpeed, ref controller.maxSpeed, 0.01f, 25f); + // controller.minSpeed = EditorGUILayout.Slider("Minimum Speed", controller.minSpeed, 0.01f, 25.0f); + // controller.maxSpeed = EditorGUILayout.Slider("Maximum Speed", controller.maxSpeed, 0.01f, 25.0f); controller.boidSeparationRange = EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f); controller.boundaryForce = EditorGUILayout.Slider("Boundary Force", controller.boundaryForce, 0.25f, 50f); controller.maxSteerForce = EditorGUILayout.Slider("Max Steer Force", controller.maxSteerForce, 1f, 500f); From 30dd4a1100f1396f7c854f324c6ac9606053de74 Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 27 May 2020 19:36:07 -0500 Subject: [PATCH 03/19] add separate draw (optional redraw) method, new drawArc and drawArcCenetered methods for FOV --- Boids/Assets/Scripts/Boid.cs | 52 +++++++++++++++++++++++--- Boids/Assets/Scripts/BoidController.cs | 3 +- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 5e0cefc..e5678ad 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -220,9 +220,7 @@ public class Boid : MonoBehaviour { var triangle = transform.GetComponent(); triangle.meshRenderer.material.color = Color.red; - // Add a LineRenderer for Radius Drawing - DrawCircle(_parent.boidSeparationRange, "Separation Range Circle"); - DrawCircle(_parent.boidGroupRange, "Group Range Circle"); + Draw(); } // Disable focusing, removing LineRenderers and resetting color @@ -238,6 +236,20 @@ public class Boid : MonoBehaviour { Destroy(child.gameObject); } + private void Draw(bool redraw = false) { + if (redraw) + foreach (Transform child in transform) + Destroy(child.gameObject); + + // Add a LineRenderer for Radius Drawing + DrawCircle(_parent.boidSeparationRange, "Separation Range Circle"); + DrawCircle(_parent.boidGroupRange, "Group Range Circle"); + + // Draw FOV Line + DrawArcCentered((_parent.boidSeparationRange + _parent.boidGroupRange) / 2f, transform.eulerAngles.z, + _parent.boidFOV, "FOV Arc"); + } + private void DrawCircle(float radius, string childName) { // Create a new child GameObject to hold the LineRenderer Component var child = new GameObject(childName); @@ -245,8 +257,6 @@ public class Boid : MonoBehaviour { child.transform.position = transform.position; var line = child.AddComponent(); - _parent.circleVertexCount = 360; - // Setup LineRenderer properties line.useWorldSpace = false; line.startWidth = _parent.circleWidth; @@ -264,4 +274,36 @@ public class Boid : MonoBehaviour { // Add points to LineRenderer line.SetPositions(points); } + + private void DrawArcCentered(float radius, float centerAngle, float angleWidth, string childName) { + DrawArc(radius, centerAngle - angleWidth / 2f, centerAngle + angleWidth / 2f, childName); + } + + private void DrawArc(float radius, float from, float to, string childName) { + // Create a new child GameObject to hold the LineRenderer Component + var child = new GameObject(childName); + child.transform.SetParent(transform); + child.transform.position = transform.position; + var line = child.AddComponent(); + + int vertexCount = _parent.arcVertexCount != -1 ? _parent.arcVertexCount : (int) Mathf.Abs(from - to) * 2; + + // Setup LineRenderer properties + line.useWorldSpace = false; + line.startWidth = _parent.circleWidth; + line.endWidth = _parent.circleWidth; + line.positionCount = vertexCount + 1; + + // Calculate points for circle + var pointCount = vertexCount + 1; + var points = new Vector3[pointCount]; + for (int i = 0; i < pointCount; i++) { + var rad = Mathf.Deg2Rad * Mathf.LerpAngle(from, to, i / (float) pointCount); + // var rad = Mathf.Deg2Rad * (i * 360f / _parent.circleVertexCount); + points[i] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); + } + + // Add points to LineRenderer + line.SetPositions(points); + } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index 0b5efcf..ca5b3ed 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -34,7 +34,8 @@ public class BoidController : MonoBehaviour { [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 = 40; // The number of vertices for circles displayed + [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 float circleWidth = 0.1f; // Width of circle [SerializeField] public float maxSteerForce = 10f; [SerializeField] public float boidFOV = 160; From 303e846e0f4a0eb657d5c581310ec8e2a51b1a54 Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 27 May 2020 20:05:26 -0500 Subject: [PATCH 04/19] add checks for group/sep/fov checks to recreate LineRenderers --- Boids/Assets/Scripts/Boid.cs | 26 +++++++++----------- Boids/Assets/Scripts/BoidControllerEditor.cs | 10 +++++--- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index e5678ad..452c589 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -29,7 +29,10 @@ public class Boid : MonoBehaviour { // Updates the rotation of the object based on the Velocity transform.eulerAngles = new Vector3(0, 0, Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y)); - // Skip Flock Calculations if wrapping in progress + if(isFocused) + Draw(true); + + // Skip Flock Calculations if wrapping in progress if (_isWrappingX || _isWrappingY) { UpdateCenteringVelocity(); _position += _centeringVelocity * Time.deltaTime; @@ -72,14 +75,6 @@ public class Boid : MonoBehaviour { private void OnDrawGizmos() { // Show # of Boids in Neighborhood Handles.Label(transform.position, $"{_latestNeighborhoodCount}"); - - // Draw a Wire Arc visualizing FOV - if (isFocused) { - float angle = transform.eulerAngles.z + (_parent.boidFOV / 2f); - Vector3 from = Quaternion.AngleAxis(angle, Vector3.up) * Vector3.forward; - Handles.DrawWireArc(transform.position, transform.forward, from, _parent.boidFOV, - (_parent.boidGroupRange + _parent.boidSeparationRange) / 2f); - } } public Vector3 DirectionFromAngle(float _angleInDeg, bool _global) { @@ -236,7 +231,7 @@ public class Boid : MonoBehaviour { Destroy(child.gameObject); } - private void Draw(bool redraw = false) { + public void Draw(bool redraw = false) { if (redraw) foreach (Transform child in transform) Destroy(child.gameObject); @@ -292,17 +287,20 @@ public class Boid : MonoBehaviour { line.useWorldSpace = false; line.startWidth = _parent.circleWidth; line.endWidth = _parent.circleWidth; - line.positionCount = vertexCount + 1; + line.positionCount = vertexCount + 1 + 2; // Calculate points for circle var pointCount = vertexCount + 1; - var points = new Vector3[pointCount]; + var points = new Vector3[pointCount + 2]; for (int i = 0; i < pointCount; i++) { - var rad = Mathf.Deg2Rad * Mathf.LerpAngle(from, to, i / (float) pointCount); + var rad = Mathf.Deg2Rad * (180 - Mathf.LerpAngle(from, to, i / (float) pointCount)); // var rad = Mathf.Deg2Rad * (i * 360f / _parent.circleVertexCount); - points[i] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); + points[i + 1] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); } + points[0] = new Vector3(0, 0, 0); + points[points.Length - 1] = points[0]; + // Add points to LineRenderer line.SetPositions(points); } diff --git a/Boids/Assets/Scripts/BoidControllerEditor.cs b/Boids/Assets/Scripts/BoidControllerEditor.cs index 644773b..b3121be 100644 --- a/Boids/Assets/Scripts/BoidControllerEditor.cs +++ b/Boids/Assets/Scripts/BoidControllerEditor.cs @@ -20,16 +20,20 @@ public class BoidControllerEditor : Editor { } // Basic Boid Controller Attributes - controller.boidGroupRange = EditorGUILayout.Slider("Group Range", controller.boidGroupRange, 0.01f, 7.5f); controller.boidStartVelocity = EditorGUILayout.Slider("Start Velocity", controller.boidStartVelocity, 0.01f, 25.0f); EditorGUILayout.MinMaxSlider("Speed Limit", ref controller.minSpeed, ref controller.maxSpeed, 0.01f, 25f); // controller.minSpeed = EditorGUILayout.Slider("Minimum Speed", controller.minSpeed, 0.01f, 25.0f); // controller.maxSpeed = EditorGUILayout.Slider("Maximum Speed", controller.maxSpeed, 0.01f, 25.0f); - controller.boidSeparationRange = EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f); controller.boundaryForce = EditorGUILayout.Slider("Boundary Force", controller.boundaryForce, 0.25f, 50f); controller.maxSteerForce = EditorGUILayout.Slider("Max Steer Force", controller.maxSteerForce, 1f, 500f); + + EditorGUI.BeginChangeCheck(); + 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); - + if (EditorGUI.EndChangeCheck()) + controller.focusedBoid.Draw(true); + // Boid Bias Attributes controller.alignmentBias = EditorGUILayout.Slider("Alignment Bias", controller.alignmentBias, 0.001f, 1.5f); controller.cohesionBias = EditorGUILayout.Slider("Cohesion Bias", controller.cohesionBias, 0.001f, 1.5f); From 55dec29413f91a54ba497787f77c353033205179 Mon Sep 17 00:00:00 2001 From: Xevion Date: Wed, 27 May 2020 22:59:24 -0500 Subject: [PATCH 05/19] add better redraw checks for EditorGUI, add build macro (CustomEditor needed), remove target frame rate --- Boids/Assets/Scripts/Boid.cs | 9 ++++----- Boids/Assets/Scripts/BoidControllerEditor.cs | 17 +++++++++++------ Boids/Assets/Scripts/UIController.cs | 2 +- Boids/ProjectSettings/GraphicsSettings.asset | 1 - 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 452c589..1ae6104 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -29,10 +29,7 @@ public class Boid : MonoBehaviour { // Updates the rotation of the object based on the Velocity transform.eulerAngles = new Vector3(0, 0, Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y)); - if(isFocused) - Draw(true); - - // Skip Flock Calculations if wrapping in progress + // Skip Flock Calculations if wrapping in progress if (_isWrappingX || _isWrappingY) { UpdateCenteringVelocity(); _position += _centeringVelocity * Time.deltaTime; @@ -72,10 +69,12 @@ public class Boid : MonoBehaviour { Wrapping(); } +#if UNITY_EDITOR private void OnDrawGizmos() { // Show # of Boids in Neighborhood Handles.Label(transform.position, $"{_latestNeighborhoodCount}"); } +#endif public Vector3 DirectionFromAngle(float _angleInDeg, bool _global) { if (_global == false) { @@ -293,8 +292,8 @@ public class Boid : MonoBehaviour { var pointCount = vertexCount + 1; var points = new Vector3[pointCount + 2]; for (int i = 0; i < pointCount; i++) { + // Magic '180 - angle' var rad = Mathf.Deg2Rad * (180 - Mathf.LerpAngle(from, to, i / (float) pointCount)); - // var rad = Mathf.Deg2Rad * (i * 360f / _parent.circleVertexCount); points[i + 1] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); } diff --git a/Boids/Assets/Scripts/BoidControllerEditor.cs b/Boids/Assets/Scripts/BoidControllerEditor.cs index b3121be..e248ec5 100644 --- a/Boids/Assets/Scripts/BoidControllerEditor.cs +++ b/Boids/Assets/Scripts/BoidControllerEditor.cs @@ -6,7 +6,8 @@ using UnityEngine; public class BoidControllerEditor : Editor { public override void OnInspectorGUI() { var controller = (BoidController) target; - + bool redraw = false; + // Boid Count update EditorGUI.BeginChangeCheck(); controller.boidCount = EditorGUILayout.IntSlider("Boid Count", controller.boidCount, 1, 500); @@ -31,18 +32,16 @@ public class BoidControllerEditor : 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); - if (EditorGUI.EndChangeCheck()) - controller.focusedBoid.Draw(true); + redraw = redraw || EditorGUI.EndChangeCheck(); - // Boid Bias Attributes + // Boid Bias Attributes controller.alignmentBias = EditorGUILayout.Slider("Alignment Bias", controller.alignmentBias, 0.001f, 1.5f); controller.cohesionBias = EditorGUILayout.Slider("Cohesion Bias", controller.cohesionBias, 0.001f, 1.5f); controller.separationBias = EditorGUILayout.Slider("Separation Bias", controller.separationBias, 0.001f, 2.5f); controller.boundaryBias = EditorGUILayout.Slider("Boundary Bias", controller.boundaryBias, 0.01f, 1.5f); controller.localFlocks = EditorGUILayout.Toggle("Use Groups?", controller.localFlocks); - controller.edgeWrapping = EditorGUILayout.Toggle("Enforce Wrapping?", controller.edgeWrapping); - + controller.edgeWrapping = EditorGUILayout.Toggle("Enable Wrapping?", controller.edgeWrapping); controller.enableAlignment = EditorGUILayout.Toggle("Enable Alignment?", controller.enableAlignment); controller.enableCohesion = EditorGUILayout.Toggle("Enable Cohesion?", controller.enableCohesion); controller.enableSeparation = EditorGUILayout.Toggle("Enable Separation?", controller.enableSeparation); @@ -50,8 +49,14 @@ public class BoidControllerEditor : Editor { controller.enableFOVChecks = EditorGUILayout.Toggle("Enable FOV?", controller.enableFOVChecks); // Boid Rendering + EditorGUI.BeginChangeCheck(); controller.circleVertexCount = EditorGUILayout.IntSlider("Circle Vertex Count", controller.circleVertexCount, 4, 360); controller.circleWidth = EditorGUILayout.Slider("Circle Line Width", controller.circleWidth, 0.01f, 1f); + redraw = redraw || EditorGUI.EndChangeCheck(); + + // Inspector elements related to Boid Focusing have changed - redraw! + if (redraw) + controller.focusedBoid.Draw(true); } } #endif \ No newline at end of file diff --git a/Boids/Assets/Scripts/UIController.cs b/Boids/Assets/Scripts/UIController.cs index 06f6ce4..d0bd109 100644 --- a/Boids/Assets/Scripts/UIController.cs +++ b/Boids/Assets/Scripts/UIController.cs @@ -76,7 +76,7 @@ public class UIController : MonoBehaviour { private void Start() { // Set Target Application Framerate - Application.targetFrameRate = 90; + // Application.targetFrameRate = 90; // Basic variable setup _currentUI = UIStance.Title; diff --git a/Boids/ProjectSettings/GraphicsSettings.asset b/Boids/ProjectSettings/GraphicsSettings.asset index 3486ea4..ab4d074 100644 --- a/Boids/ProjectSettings/GraphicsSettings.asset +++ b/Boids/ProjectSettings/GraphicsSettings.asset @@ -34,7 +34,6 @@ GraphicsSettings: - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0} - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} - - {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0} m_PreloadedShaders: [] m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} From 25a47d9af5b8493dc537a6a915a507ff96af25b5 Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 28 May 2020 08:32:40 -0500 Subject: [PATCH 06/19] Move BoidControllerEditor.cs into Editor folder, Add BUGS.md --- BUGS.md | 19 +++++++++++++++++++ .../BoidControllerEditor.cs | 6 ++---- .../BoidControllerEditor.cs.meta | 0 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 BUGS.md rename Boids/Assets/{Scripts => Editor}/BoidControllerEditor.cs (98%) rename Boids/Assets/{Scripts => Editor}/BoidControllerEditor.cs.meta (100%) diff --git a/BUGS.md b/BUGS.md new file mode 100644 index 0000000..0997547 --- /dev/null +++ b/BUGS.md @@ -0,0 +1,19 @@ +# bugs + +A list of frustrating or curious bugs. + +- DrawCircle Function Draw on Incorrect Axis + - For a long period of time, I couldn't figure out why my DrawCircle function was only drawing a straight line. + I reworked the code, looked online and did everything I could to get the function working before I gave up. + A day later, I switched from 2D mode to Freecam mode, and I finally saw it. + The circle was drew aligned on the incorrect axis, causing it to appear as a single line. + The fix was was just swapping one argument with the next. `(x, 0, y) -> (x, y, 0)` +- OnCenteringVelocity applied at > 200x correct rate + - When I implemented `Time.deltaTime` based velocity calculations, I didn't correct the OnCenteringVelocity implementation. + This caused a strange behaviour that looked very similar to a incorrect boundary calculation. + I spent some time checking Boundary/Wrapping related code before I forgot it, as I hadn't modified it. + It didn't take that long, but I'm still surprised I caught it since the mistake is so small. + The error was that since the `Time.deltaTime` value is not multiplied (scaling the 1x multiplier down to 0.02x), + the velocity would speed it to an incredible speed for a single frame. + This would cause all edge wrapped boids to skip a certain distance to the center of the rectangle which looked like + an edge wrapping/boundary error. \ No newline at end of file diff --git a/Boids/Assets/Scripts/BoidControllerEditor.cs b/Boids/Assets/Editor/BoidControllerEditor.cs similarity index 98% rename from Boids/Assets/Scripts/BoidControllerEditor.cs rename to Boids/Assets/Editor/BoidControllerEditor.cs index e248ec5..c94d717 100644 --- a/Boids/Assets/Scripts/BoidControllerEditor.cs +++ b/Boids/Assets/Editor/BoidControllerEditor.cs @@ -1,5 +1,4 @@ -#if UNITY_EDITOR -using UnityEditor; +using UnityEditor; using UnityEngine; [CustomEditor(typeof(BoidController))] @@ -58,5 +57,4 @@ public class BoidControllerEditor : Editor { if (redraw) controller.focusedBoid.Draw(true); } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Boids/Assets/Scripts/BoidControllerEditor.cs.meta b/Boids/Assets/Editor/BoidControllerEditor.cs.meta similarity index 100% rename from Boids/Assets/Scripts/BoidControllerEditor.cs.meta rename to Boids/Assets/Editor/BoidControllerEditor.cs.meta From 8e976e31962bde51d7de77afbf6bce1567a7b04a Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 28 May 2020 08:36:04 -0500 Subject: [PATCH 07/19] private isFocused, remove _renderers, remove unused DirectionFromAngle, make Draw's redraw arg explicit --- Boids/Assets/Scripts/Boid.cs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 1ae6104..2d8c273 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -10,16 +10,14 @@ public class Boid : MonoBehaviour { [NonSerialized] private Vector2 _velocity; [NonSerialized] private bool _isWrappingX = false; [NonSerialized] private bool _isWrappingY = false; - [NonSerialized] private Renderer[] _renderers; [NonSerialized] private Vector2 _centeringVelocity; [NonSerialized] private int _latestNeighborhoodCount = 0; [NonSerialized] private BoidController _parent; - [NonSerialized] public bool isFocused = false; + [NonSerialized] private bool _isFocused = false; private void Start() { _parent = transform.parent .GetComponent(); // Parent used to perform physics math without caching - _renderers = transform.GetComponents(); // Acquire Renderer(s) to check for Boid visibility _velocity = Util.GetRandomVelocity(_parent.boidStartVelocity); // Acquire a Velocity Vector with a magnitude _position = transform.position; // Track 2D position separately transform.name = $"Boid {transform.GetSiblingIndex()}"; // Name the Game Object so Boids can be tracked somewhat @@ -76,14 +74,6 @@ public class Boid : MonoBehaviour { } #endif - public Vector3 DirectionFromAngle(float _angleInDeg, bool _global) { - if (_global == false) { - _angleInDeg += transform.eulerAngles.z; - } - - return new Vector3(Mathf.Sin(_angleInDeg * Mathf.Deg2Rad), Mathf.Cos(_angleInDeg * Mathf.Deg2Rad), 0); - } - private Vector2 SteerTowards(Vector2 vector) { Vector2 v = vector.normalized * _parent.maxSpeed - _velocity; return Vector2.ClampMagnitude(v, _parent.maxSteerForce); @@ -185,9 +175,11 @@ public class Boid : MonoBehaviour { List flock = new List(); foreach (Boid boid in boids) { + // Distance Check if (boid == this || Vector2.Distance(this._position, boid._position) > radius) continue; + // FOV Check if (_parent.enableFOVChecks) { float angle1 = Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y); float angle2 = Mathf.Rad2Deg * -Mathf.Atan2(boid._velocity.x, boid._velocity.y); @@ -203,23 +195,23 @@ public class Boid : MonoBehaviour { // Sets up a Boid to be 'Focused', adds Circles around object and changes color public void EnableFocusing() { - if (isFocused) { + if (_isFocused) { Debug.LogWarning("enableFocusing called on previously focused Boid"); return; } - isFocused = true; + _isFocused = true; // Update Mesh Material Color var triangle = transform.GetComponent(); triangle.meshRenderer.material.color = Color.red; - Draw(); + Draw(false); } // Disable focusing, removing LineRenderers and resetting color public void DisableFocusing() { - isFocused = false; + _isFocused = false; // Update Mesh Material Color var oldTriangle = transform.GetComponent(); @@ -230,7 +222,7 @@ public class Boid : MonoBehaviour { Destroy(child.gameObject); } - public void Draw(bool redraw = false) { + public void Draw(bool redraw) { if (redraw) foreach (Transform child in transform) Destroy(child.gameObject); From 37b54ded30bffaff9fa664ad70570783f8de3452 Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 28 May 2020 22:59:50 -0500 Subject: [PATCH 08/19] moved BoidEditor/BoidControllerEditor scripts away for proper Build procedure (no macro) --- Boids/Assets/Editor/BoidControllerEditor.cs | 22 ++++++++++++--------- Boids/Assets/Editor/BoidEditor.cs | 17 ++++++++++++++++ Boids/Assets/Editor/BoidEditor.cs.meta | 3 +++ Boids/Assets/Scripts/Boid.cs | 12 ++--------- 4 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 Boids/Assets/Editor/BoidEditor.cs create mode 100644 Boids/Assets/Editor/BoidEditor.cs.meta diff --git a/Boids/Assets/Editor/BoidControllerEditor.cs b/Boids/Assets/Editor/BoidControllerEditor.cs index c94d717..44ea563 100644 --- a/Boids/Assets/Editor/BoidControllerEditor.cs +++ b/Boids/Assets/Editor/BoidControllerEditor.cs @@ -2,7 +2,7 @@ using UnityEngine; [CustomEditor(typeof(BoidController))] -public class BoidControllerEditor : Editor { +public class BoidControllerEditor : UnityEditor.Editor { public override void OnInspectorGUI() { var controller = (BoidController) target; bool redraw = false; @@ -20,23 +20,26 @@ public class BoidControllerEditor : Editor { } // Basic Boid Controller Attributes - controller.boidStartVelocity = EditorGUILayout.Slider("Start Velocity", controller.boidStartVelocity, 0.01f, 25.0f); - EditorGUILayout.MinMaxSlider("Speed Limit", ref controller.minSpeed, ref controller.maxSpeed, 0.01f, 25f); + controller.boidStartVelocity = + EditorGUILayout.Slider("Start Velocity", controller.boidStartVelocity, 0.01f, 25.0f); + EditorGUILayout.MinMaxSlider("Speed Limit", ref controller.minSpeed, ref controller.maxSpeed, 0.01f, 25f); // controller.minSpeed = EditorGUILayout.Slider("Minimum Speed", controller.minSpeed, 0.01f, 25.0f); // controller.maxSpeed = EditorGUILayout.Slider("Maximum Speed", controller.maxSpeed, 0.01f, 25.0f); controller.boundaryForce = EditorGUILayout.Slider("Boundary Force", controller.boundaryForce, 0.25f, 50f); controller.maxSteerForce = EditorGUILayout.Slider("Max Steer Force", controller.maxSteerForce, 1f, 500f); - + EditorGUI.BeginChangeCheck(); 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.boidSeparationRange = + EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f); controller.boidFOV = EditorGUILayout.Slider("Boid FOV", controller.boidFOV, 1f, 360f); redraw = redraw || EditorGUI.EndChangeCheck(); - - // Boid Bias Attributes + + // Boid Bias Attributes controller.alignmentBias = EditorGUILayout.Slider("Alignment Bias", controller.alignmentBias, 0.001f, 1.5f); controller.cohesionBias = EditorGUILayout.Slider("Cohesion Bias", controller.cohesionBias, 0.001f, 1.5f); - controller.separationBias = EditorGUILayout.Slider("Separation Bias", controller.separationBias, 0.001f, 2.5f); + controller.separationBias = + EditorGUILayout.Slider("Separation Bias", controller.separationBias, 0.001f, 2.5f); controller.boundaryBias = EditorGUILayout.Slider("Boundary Bias", controller.boundaryBias, 0.01f, 1.5f); controller.localFlocks = EditorGUILayout.Toggle("Use Groups?", controller.localFlocks); @@ -49,7 +52,8 @@ public class BoidControllerEditor : Editor { // Boid Rendering EditorGUI.BeginChangeCheck(); - controller.circleVertexCount = EditorGUILayout.IntSlider("Circle Vertex Count", controller.circleVertexCount, 4, 360); + controller.circleVertexCount = + EditorGUILayout.IntSlider("Circle Vertex Count", controller.circleVertexCount, 4, 360); controller.circleWidth = EditorGUILayout.Slider("Circle Line Width", controller.circleWidth, 0.01f, 1f); redraw = redraw || EditorGUI.EndChangeCheck(); diff --git a/Boids/Assets/Editor/BoidEditor.cs b/Boids/Assets/Editor/BoidEditor.cs new file mode 100644 index 0000000..dd7e30d --- /dev/null +++ b/Boids/Assets/Editor/BoidEditor.cs @@ -0,0 +1,17 @@ +using UnityEditor; +using UnityEngine; + +// [CustomEditor(typeof(Boid))] +// public class BoidEditor : UnityEditor.Editor { +// public override void OnInspectorGUI() { +// base.OnInspectorGUI(); +// } +// } + +public class BoidGizmoDrawer { + [DrawGizmo(GizmoType.NonSelected | GizmoType.Selected)] + static void DrawGizmo(Boid boid, GizmoType gizmoType) { + // Simply draw the # of Boids within the perceived flock + Handles.Label(boid.transform.position, $"{boid.latestNeighborhoodCount}"); + } +} \ No newline at end of file diff --git a/Boids/Assets/Editor/BoidEditor.cs.meta b/Boids/Assets/Editor/BoidEditor.cs.meta new file mode 100644 index 0000000..02549a6 --- /dev/null +++ b/Boids/Assets/Editor/BoidEditor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f4b27abbe35a49dd946d059c0ebe4cea +timeCreated: 1590672982 \ No newline at end of file diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 2d8c273..4207fb8 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using UnityEditor; using UnityEngine; // Boids are represented by a moving, rotating triangle. @@ -11,7 +10,7 @@ public class Boid : MonoBehaviour { [NonSerialized] private bool _isWrappingX = false; [NonSerialized] private bool _isWrappingY = false; [NonSerialized] private Vector2 _centeringVelocity; - [NonSerialized] private int _latestNeighborhoodCount = 0; + [NonSerialized] public int latestNeighborhoodCount = 0; [NonSerialized] private BoidController _parent; [NonSerialized] private bool _isFocused = false; @@ -36,7 +35,7 @@ public class Boid : MonoBehaviour { else { Vector2 acceleration = Vector2.zero; List flock = _parent.localFlocks ? GetFlock(_parent.boids, _parent.boidGroupRange) : _parent.boids; - _latestNeighborhoodCount = flock.Count; + latestNeighborhoodCount = flock.Count; // Calculate all offsets and multiple by magnitudes given if (flock.Count > 0) { @@ -67,13 +66,6 @@ public class Boid : MonoBehaviour { Wrapping(); } -#if UNITY_EDITOR - private void OnDrawGizmos() { - // Show # of Boids in Neighborhood - Handles.Label(transform.position, $"{_latestNeighborhoodCount}"); - } -#endif - private Vector2 SteerTowards(Vector2 vector) { Vector2 v = vector.normalized * _parent.maxSpeed - _velocity; return Vector2.ClampMagnitude(v, _parent.maxSteerForce); From 049879522aeacef2a24fd1b5b9417cf3fe064c2e Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 28 May 2020 23:00:26 -0500 Subject: [PATCH 09/19] banner psd meta file, assembly csharp editor dot csproj settings (unversioned file updates) --- .../Assembly-CSharp-Editor.csproj.DotSettings | 2 + Boids/Assets/Resources/Icons/banner.psd.meta | 90 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 Boids/Assembly-CSharp-Editor.csproj.DotSettings create mode 100644 Boids/Assets/Resources/Icons/banner.psd.meta diff --git a/Boids/Assembly-CSharp-Editor.csproj.DotSettings b/Boids/Assembly-CSharp-Editor.csproj.DotSettings new file mode 100644 index 0000000..5ac0881 --- /dev/null +++ b/Boids/Assembly-CSharp-Editor.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/Boids/Assets/Resources/Icons/banner.psd.meta b/Boids/Assets/Resources/Icons/banner.psd.meta new file mode 100644 index 0000000..5273e87 --- /dev/null +++ b/Boids/Assets/Resources/Icons/banner.psd.meta @@ -0,0 +1,90 @@ +fileFormatVersion: 2 +guid: 24a4da36a55f5154f8359f0e4520bc1d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 10 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - serializedVersion: 2 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 20a24599605d8f1458a67cb3b687fdfa + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: From e6ec6a3942714d5d446eb8830a409e046714025a Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 4 Jun 2020 22:51:32 -0500 Subject: [PATCH 10/19] small comment edit --- Boids/Assets/Scripts/Boid.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 4207fb8..2f18707 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using UnityEngine; // Boids are represented by a moving, rotating triangle. -// Boids should communicate with sibling Boids +// Boids should communicate with sibling Boids via the parental BoidController object public class Boid : MonoBehaviour { [NonSerialized] private Vector2 _position = Vector2.zero; [NonSerialized] private Vector2 _velocity; From 8ee9f33082e4418783b75d348ce66fe5eb037c8e Mon Sep 17 00:00:00 2001 From: Xevion Date: Thu, 4 Jun 2020 23:06:28 -0500 Subject: [PATCH 11/19] transform sceneview to focus on specific boid when one is focused, allow size change, use orthographic rot --- Boids/Assets/Editor/BoidEditor.cs | 1 + Boids/Assets/Scripts/BoidController.cs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Boids/Assets/Editor/BoidEditor.cs b/Boids/Assets/Editor/BoidEditor.cs index dd7e30d..a696307 100644 --- a/Boids/Assets/Editor/BoidEditor.cs +++ b/Boids/Assets/Editor/BoidEditor.cs @@ -12,6 +12,7 @@ public class BoidGizmoDrawer { [DrawGizmo(GizmoType.NonSelected | GizmoType.Selected)] static void DrawGizmo(Boid boid, GizmoType gizmoType) { // Simply draw the # of Boids within the perceived flock + Handles.Label(boid.transform.position, $"{boid.latestNeighborhoodCount}"); } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index ca5b3ed..fe999db 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -78,6 +78,12 @@ public class BoidController : MonoBehaviour { focusedBoid = boids[Random.Range(0, boids.Count)]; focusedBoid.EnableFocusing(); } + + // Focus on the boid in scene view when one is focused + #if UNITY_EDITOR + if(focusedBoid != null) + SceneView.lastActiveSceneView.LookAt(focusedBoid.transform.position, Quaternion.identity); + #endif } private void Start() { From f6dd8f6c2a4b610ce082f78705b8673edfb5512c Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 17:53:55 -0500 Subject: [PATCH 12/19] update Boid velocity to angle and angle difference methods for FOV detection, finished working FOV detection --- Boids/Assets/Scripts/Boid.cs | 29 ++++++++++++++++++++--------- Boids/Assets/Scripts/Util.cs | 35 ++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 2f18707..62e2680 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -1,18 +1,20 @@ using System; using System.Collections.Generic; + using UnityEditor; using UnityEngine; // Boids are represented by a moving, rotating triangle. // Boids should communicate with sibling Boids via the parental BoidController object public class Boid : MonoBehaviour { [NonSerialized] private Vector2 _position = Vector2.zero; - [NonSerialized] private Vector2 _velocity; + [NonSerialized] public Vector2 _velocity; [NonSerialized] private bool _isWrappingX = false; [NonSerialized] private bool _isWrappingY = false; [NonSerialized] private Vector2 _centeringVelocity; [NonSerialized] public int latestNeighborhoodCount = 0; + [NonSerialized] public List latestNeighborhood; [NonSerialized] private BoidController _parent; - [NonSerialized] private bool _isFocused = false; + [NonSerialized] public bool _isFocused = false; private void Start() { _parent = transform.parent @@ -37,6 +39,10 @@ public class Boid : MonoBehaviour { List 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) @@ -173,10 +179,13 @@ public class Boid : MonoBehaviour { // FOV Check if (_parent.enableFOVChecks) { - float angle1 = Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y); - float angle2 = Mathf.Rad2Deg * -Mathf.Atan2(boid._velocity.x, boid._velocity.y); - if (Mathf.Abs(angle2 - angle1) > _parent.boidFOV / 2) + 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) continue; + } flock.Add(boid); @@ -224,7 +233,7 @@ public class Boid : MonoBehaviour { DrawCircle(_parent.boidGroupRange, "Group Range Circle"); // Draw FOV Line - DrawArcCentered((_parent.boidSeparationRange + _parent.boidGroupRange) / 2f, transform.eulerAngles.z, + DrawArcCentered(_parent.boidGroupRange, Util.Vector2ToAngle(_velocity), _parent.boidFOV, "FOV Arc"); } @@ -254,7 +263,8 @@ public class Boid : MonoBehaviour { } private void DrawArcCentered(float radius, float centerAngle, float angleWidth, string childName) { - DrawArc(radius, centerAngle - angleWidth / 2f, centerAngle + angleWidth / 2f, childName); + float half = angleWidth / 2f; + DrawArc(radius, Util.AddAngle(centerAngle, -half), Util.AddAngle(centerAngle, half), childName); } private void DrawArc(float radius, float from, float to, string childName) { @@ -275,10 +285,11 @@ public class Boid : MonoBehaviour { // Calculate points for circle var pointCount = vertexCount + 1; var points = new Vector3[pointCount + 2]; + for (int i = 0; i < pointCount; i++) { // Magic '180 - angle' - var rad = Mathf.Deg2Rad * (180 - Mathf.LerpAngle(from, to, i / (float) pointCount)); - points[i + 1] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); + var rad = Mathf.Deg2Rad * Mathf.LerpAngle(from, to, i / (float) pointCount); + points[i + 1] = new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0) * radius; } points[0] = new Vector3(0, 0, 0); diff --git a/Boids/Assets/Scripts/Util.cs b/Boids/Assets/Scripts/Util.cs index d859b41..572a62b 100644 --- a/Boids/Assets/Scripts/Util.cs +++ b/Boids/Assets/Scripts/Util.cs @@ -6,13 +6,13 @@ public class Util { var sa = Mathf.Sin(a); var rx = v.x * ca - v.y * sa; - return new Vector2((float) rx, (float) (v.x * sa + v.y * ca)); + return new Vector2(rx, v.x * sa + v.y * ca); } // Returns a velocity (Vector2) at a random angle with a specific overall magnitude public static Vector2 GetRandomVelocity(float magnitude) { var vector = new Vector2(magnitude, magnitude); - return Util.RotateBy(vector, Random.Range(0, 180)); + return RotateBy(vector, Random.Range(0, 180)); } public static Vector2 MaxVelocity(Vector2 v, float max) { @@ -27,24 +27,25 @@ public class Util { return v; } - public static Vector2 AbsVector(Vector2 vector) { - return new Vector2(vector.x, vector.y); + public static float Vector2ToAngle(Vector2 velocity) { + float result = Mathf.Rad2Deg * Mathf.Atan2(velocity.y, velocity.x); + return (result < 0) ? (360f + result) : result; } -} -public class Scale { - private Vector2 _original; - private Vector2 _new; - private Vector2 _ratio; + public static float AngleBetween(Vector2 from, Vector2 to) { + Vector2 diff = to - from; + float result = Mathf.Rad2Deg * Mathf.Atan2(diff.y, diff.x); + return (result < 0) ? (360f + result) : result; + } - public float X => _ratio.x; - public float Y => _ratio.y; + public static float AngleDifference(float angle1, float angle2) { + return Mathf.Abs((angle1 > 180 ? 360 - angle1 : angle1) - (angle2 > 180 ? 360 - angle2 : angle2)); + } - public Scale(Vector2 original, Canvas canvas) : this(original, canvas.pixelRect.size) { } - - public Scale(Vector2 original, Vector2 resized) { - _original = original; - _new = resized; - _ratio = _original / _new; + public static float AddAngle(float angle, float add) { + float result = angle + add; + if (result > 360) return result - 360; + if (result < 0) return 360 + result; + return result; } } \ No newline at end of file From d3f213717f6e8524fbff23494cbebbaaa4c6d914 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 17:59:05 -0500 Subject: [PATCH 13/19] use LookAtDirect for no lag SceneView updates, draw dotted line between latest detected neighbors, velocity display in inspector GUI, ready arc vertex inspector GUI CustomEditor --- Boids/Assets/Editor/BoidControllerEditor.cs | 4 +++- Boids/Assets/Editor/BoidEditor.cs | 20 +++++++++++++------- Boids/Assets/Scripts/BoidController.cs | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Boids/Assets/Editor/BoidControllerEditor.cs b/Boids/Assets/Editor/BoidControllerEditor.cs index 44ea563..eb2050f 100644 --- a/Boids/Assets/Editor/BoidControllerEditor.cs +++ b/Boids/Assets/Editor/BoidControllerEditor.cs @@ -54,7 +54,9 @@ public class BoidControllerEditor : UnityEditor.Editor { EditorGUI.BeginChangeCheck(); controller.circleVertexCount = EditorGUILayout.IntSlider("Circle Vertex Count", controller.circleVertexCount, 4, 360); - controller.circleWidth = EditorGUILayout.Slider("Circle Line Width", controller.circleWidth, 0.01f, 1f); + // controller.arcVertexCount = + // EditorGUILayout.IntSlider("Arc Vertex Count", controller.arcVertexCount, -1, 360); + controller.circleWidth = EditorGUILayout.Slider("Circle Line Width", controller.circleWidth, 0.01f, 1f); redraw = redraw || EditorGUI.EndChangeCheck(); // Inspector elements related to Boid Focusing have changed - redraw! diff --git a/Boids/Assets/Editor/BoidEditor.cs b/Boids/Assets/Editor/BoidEditor.cs index a696307..6686879 100644 --- a/Boids/Assets/Editor/BoidEditor.cs +++ b/Boids/Assets/Editor/BoidEditor.cs @@ -1,18 +1,24 @@ using UnityEditor; using UnityEngine; -// [CustomEditor(typeof(Boid))] -// public class BoidEditor : UnityEditor.Editor { -// public override void OnInspectorGUI() { -// base.OnInspectorGUI(); -// } -// } +[CustomEditor(typeof(Boid))] +public class BoidEditor : UnityEditor.Editor { + public override void OnInspectorGUI() { + base.OnInspectorGUI(); + + Boid boid = (Boid) target; + GUILayout.Label($"Boid heading at ({boid._velocity.x}, {boid._velocity.y})"); + } +} public class BoidGizmoDrawer { [DrawGizmo(GizmoType.NonSelected | GizmoType.Selected)] static void DrawGizmo(Boid boid, GizmoType gizmoType) { // Simply draw the # of Boids within the perceived flock + Handles.Label(boid.transform.position, $"{boid.transform.name}/{boid.latestNeighborhoodCount}"); - Handles.Label(boid.transform.position, $"{boid.latestNeighborhoodCount}"); + if(boid._isFocused) + foreach(Boid flockmate in boid.latestNeighborhood) + Handles.DrawDottedLine(boid.transform.position, flockmate.transform.position, 1f); } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index fe999db..68aece8 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -82,7 +82,7 @@ public class BoidController : MonoBehaviour { // Focus on the boid in scene view when one is focused #if UNITY_EDITOR if(focusedBoid != null) - SceneView.lastActiveSceneView.LookAt(focusedBoid.transform.position, Quaternion.identity); + SceneView.lastActiveSceneView.LookAtDirect(focusedBoid.transform.position, Quaternion.identity); #endif } From a79daf7ed747622150def0ad1a0503a56ca81145 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 18:09:35 -0500 Subject: [PATCH 14/19] ShapeDraw utility class to split draw logic --- Boids/Assets/Scripts.meta | 4 +-- Boids/Assets/Scripts/ShapeDraw.cs | 35 ++++++++++++++++++++++++++ Boids/Assets/Scripts/ShapeDraw.cs.meta | 3 +++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 Boids/Assets/Scripts/ShapeDraw.cs create mode 100644 Boids/Assets/Scripts/ShapeDraw.cs.meta diff --git a/Boids/Assets/Scripts.meta b/Boids/Assets/Scripts.meta index 4021c25..2ebc7e0 100644 --- a/Boids/Assets/Scripts.meta +++ b/Boids/Assets/Scripts.meta @@ -1,3 +1,3 @@ fileFormatVersion: 2 -guid: b50106a18d564518ba59ebb42e02f619 -timeCreated: 1589861330 \ No newline at end of file +guid: 5a23673acb15433ea9f977712582464f +timeCreated: 1591398022 \ No newline at end of file diff --git a/Boids/Assets/Scripts/ShapeDraw.cs b/Boids/Assets/Scripts/ShapeDraw.cs new file mode 100644 index 0000000..7c7b7dd --- /dev/null +++ b/Boids/Assets/Scripts/ShapeDraw.cs @@ -0,0 +1,35 @@ +using UnityEngine; + +/// +/// A simple static utility class that assists with drawing shapes using the LineRenderer class. +/// +public class ShapeDraw { + /// + /// Draw a Arc aimed straight up with a certain angle width and radius. + /// Use to point the Arc at a certain direction. + /// + /// The LineRenderer to draw the Arc upon. + /// Angle of the Arc + /// Radius of the Arc + /// Number of vertexes to be used in the arc, clamp minimum 3 + /// + public static void DrawArc(LineRenderer lineRenderer, float angle, float radius, int vertexCount) { + + } + + /// + /// Draw a Circle with a specific radius and number of vertexes (detail level) + /// + /// + public static void DrawCircle(LineRenderer lineRenderer) { + + } + + /// + /// + /// + /// + public static void RotateLineRenderer(LineRenderer lineRenderer) { + + } +} \ No newline at end of file diff --git a/Boids/Assets/Scripts/ShapeDraw.cs.meta b/Boids/Assets/Scripts/ShapeDraw.cs.meta new file mode 100644 index 0000000..bb852f7 --- /dev/null +++ b/Boids/Assets/Scripts/ShapeDraw.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 09004a14b18b4662898d7e1cc0bc6f24 +timeCreated: 1591398023 \ No newline at end of file From 4b10722a48574be47bccc783b43d7171a26f2ce0 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 18:16:25 -0500 Subject: [PATCH 15/19] move arc drawing code into ShapeDraw, remove vertex count argument --- Boids/Assets/Scripts/Boid.cs | 37 ------------------------------- Boids/Assets/Scripts/ShapeDraw.cs | 29 ++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 62e2680..934cfba 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -261,41 +261,4 @@ public class Boid : MonoBehaviour { // Add points to LineRenderer line.SetPositions(points); } - - private void DrawArcCentered(float radius, float centerAngle, float angleWidth, string childName) { - float half = angleWidth / 2f; - DrawArc(radius, Util.AddAngle(centerAngle, -half), Util.AddAngle(centerAngle, half), childName); - } - - private void DrawArc(float radius, float from, float to, string childName) { - // Create a new child GameObject to hold the LineRenderer Component - var child = new GameObject(childName); - child.transform.SetParent(transform); - child.transform.position = transform.position; - var line = child.AddComponent(); - - int vertexCount = _parent.arcVertexCount != -1 ? _parent.arcVertexCount : (int) Mathf.Abs(from - to) * 2; - - // Setup LineRenderer properties - line.useWorldSpace = false; - line.startWidth = _parent.circleWidth; - line.endWidth = _parent.circleWidth; - line.positionCount = vertexCount + 1 + 2; - - // Calculate points for circle - var pointCount = vertexCount + 1; - var points = new Vector3[pointCount + 2]; - - for (int i = 0; i < pointCount; i++) { - // Magic '180 - angle' - var rad = Mathf.Deg2Rad * Mathf.LerpAngle(from, to, i / (float) pointCount); - points[i + 1] = new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0) * radius; - } - - points[0] = new Vector3(0, 0, 0); - points[points.Length - 1] = points[0]; - - // Add points to LineRenderer - line.SetPositions(points); - } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/ShapeDraw.cs b/Boids/Assets/Scripts/ShapeDraw.cs index 7c7b7dd..176d37e 100644 --- a/Boids/Assets/Scripts/ShapeDraw.cs +++ b/Boids/Assets/Scripts/ShapeDraw.cs @@ -4,6 +4,12 @@ /// A simple static utility class that assists with drawing shapes using the LineRenderer class. /// public class ShapeDraw { + public static float CircleWidth = 1f; + public static float ArcWidth = 1f; + public static int CircleVertexCount = 360; + public static int ArcVertexCount = 77; + + /// /// Draw a Arc aimed straight up with a certain angle width and radius. /// Use to point the Arc at a certain direction. @@ -11,10 +17,29 @@ public class ShapeDraw { /// The LineRenderer to draw the Arc upon. /// Angle of the Arc /// Radius of the Arc - /// Number of vertexes to be used in the arc, clamp minimum 3 /// - public static void DrawArc(LineRenderer lineRenderer, float angle, float radius, int vertexCount) { + public static void DrawArc(LineRenderer lineRenderer, float angle, float radius) { + // Setup LineRenderer properties + lineRenderer.useWorldSpace = false; + lineRenderer.startWidth = ArcWidth; + lineRenderer.endWidth = ArcWidth; + lineRenderer.positionCount = ArcVertexCount + 1 + 2; + + // Calculate points for circle + var pointCount = ArcVertexCount + 1; + var points = new Vector3[pointCount + 2]; + for (int i = 0; i < pointCount; i++) { + // Magic '180 - angle' + var rad = Mathf.Deg2Rad * Mathf.LerpAngle(0, angle, i / (float) pointCount); + points[i + 1] = new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0) * radius; + } + + points[0] = new Vector3(0, 0, 0); + points[points.Length - 1] = points[0]; + + // Add points to LineRenderer + lineRenderer.SetPositions(points); } /// From 1188a75d9ebedc74c6873e4698cffc74c02bcf6a Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 18:28:44 -0500 Subject: [PATCH 16/19] new GetLineRenderer method, port DrawCircle code --- Boids/Assets/Scripts/Boid.cs | 40 +++++++++++-------------------- Boids/Assets/Scripts/ShapeDraw.cs | 19 +++++++++++++-- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 934cfba..71cb7b7 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -197,7 +197,7 @@ public class Boid : MonoBehaviour { // Sets up a Boid to be 'Focused', adds Circles around object and changes color public void EnableFocusing() { if (_isFocused) { - Debug.LogWarning("enableFocusing called on previously focused Boid"); + Debug.LogWarning($"enableFocusing called on previously focused Boid ({transform.name})"); return; } @@ -207,6 +207,7 @@ public class Boid : MonoBehaviour { var triangle = transform.GetComponent(); triangle.meshRenderer.material.color = Color.red; + // Draw all focus related elements Draw(false); } @@ -223,6 +224,18 @@ public class Boid : MonoBehaviour { Destroy(child.gameObject); } + /// + /// returns a new LineRenderer component stored on a child GameObject. + /// + /// The name of the associated child GameObject + /// A LineRenderer + public LineRenderer GetLineRenderer(string childName) { + var child = new GameObject(childName); + child.transform.SetParent(transform); + child.transform.position = transform.position; + return child.AddComponent(); + } + public void Draw(bool redraw) { if (redraw) foreach (Transform child in transform) @@ -236,29 +249,4 @@ public class Boid : MonoBehaviour { DrawArcCentered(_parent.boidGroupRange, Util.Vector2ToAngle(_velocity), _parent.boidFOV, "FOV Arc"); } - - private void DrawCircle(float radius, string childName) { - // Create a new child GameObject to hold the LineRenderer Component - var child = new GameObject(childName); - child.transform.SetParent(transform); - child.transform.position = transform.position; - var line = child.AddComponent(); - - // Setup LineRenderer properties - line.useWorldSpace = false; - line.startWidth = _parent.circleWidth; - line.endWidth = _parent.circleWidth; - line.positionCount = _parent.circleVertexCount + 1; - - // Calculate points for circle - var pointCount = _parent.circleVertexCount + 1; - var points = new Vector3[pointCount]; - for (int i = 0; i < pointCount; i++) { - var rad = Mathf.Deg2Rad * (i * 360f / _parent.circleVertexCount); - points[i] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); - } - - // Add points to LineRenderer - line.SetPositions(points); - } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/ShapeDraw.cs b/Boids/Assets/Scripts/ShapeDraw.cs index 176d37e..b5502f1 100644 --- a/Boids/Assets/Scripts/ShapeDraw.cs +++ b/Boids/Assets/Scripts/ShapeDraw.cs @@ -46,8 +46,23 @@ public class ShapeDraw { /// Draw a Circle with a specific radius and number of vertexes (detail level) /// /// - public static void DrawCircle(LineRenderer lineRenderer) { - + public static void DrawCircle(LineRenderer lineRenderer, float radius) { + // Setup LineRenderer properties + lineRenderer.useWorldSpace = false; + lineRenderer.startWidth = CircleWidth; + lineRenderer.endWidth = CircleWidth; + lineRenderer.positionCount = CircleVertexCount + 1; + + // Calculate points for circle + var pointCount = CircleVertexCount + 1; + var points = new Vector3[pointCount]; + for (int i = 0; i < pointCount; i++) { + var rad = Mathf.Deg2Rad * (i * 360f / CircleVertexCount); + points[i] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); + } + + // Add points to LineRenderer + lineRenderer.SetPositions(points); } /// From 92d1e3efefd5615d4086ded340f5d005fe44e101 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 19:15:54 -0500 Subject: [PATCH 17/19] reset circle/arc/ width/vertexcount with shapedraw, timescale edit, new static array LineRenderers, finished arc drawing base --- Boids/Assets/Scripts/Boid.cs | 41 +++++++++++++++++++------- Boids/Assets/Scripts/BoidController.cs | 7 +++++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 71cb7b7..6da9e05 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -15,6 +15,8 @@ public class Boid : MonoBehaviour { [NonSerialized] public List latestNeighborhood; [NonSerialized] private BoidController _parent; [NonSerialized] public bool _isFocused = false; + [NonSerialized] private LineRenderer[] _lineRenderers; + private void Start() { _parent = transform.parent @@ -187,7 +189,8 @@ public class Boid : MonoBehaviour { continue; } - + + // Boid passed all checks, add to local Flock list flock.Add(boid); } @@ -203,6 +206,12 @@ public class Boid : MonoBehaviour { _isFocused = true; + // Create all LineRenderers + _lineRenderers = new LineRenderer[3]; + _lineRenderers[0] = GetLineRenderer("Group Range"); + _lineRenderers[1] = GetLineRenderer("Separation Range"); + _lineRenderers[2] = GetLineRenderer("FOV Arc"); + // Update Mesh Material Color var triangle = transform.GetComponent(); triangle.meshRenderer.material.color = Color.red; @@ -218,10 +227,12 @@ public class Boid : MonoBehaviour { // Update Mesh Material Color var oldTriangle = transform.GetComponent(); oldTriangle.meshRenderer.material.color = new Color32(49, 61, 178, 255); - + + // Destroy Line Renderers (and child GameObjects) foreach (Transform child in transform) Destroy(child.gameObject); + Array.Clear(_lineRenderers, 0, _lineRenderers.Length); } /// @@ -231,22 +242,30 @@ public class Boid : MonoBehaviour { /// A LineRenderer public LineRenderer GetLineRenderer(string childName) { var child = new GameObject(childName); + // Make object a child of Boid, set position as such child.transform.SetParent(transform); child.transform.position = transform.position; + // add and return LineRenderer component return child.AddComponent(); } public void Draw(bool redraw) { - if (redraw) - foreach (Transform child in transform) - Destroy(child.gameObject); - + // Clear positions when redrawing + if(redraw) + foreach (LineRenderer lineRenderer in _lineRenderers) + lineRenderer.positionCount = 0; + // Add a LineRenderer for Radius Drawing - DrawCircle(_parent.boidSeparationRange, "Separation Range Circle"); - DrawCircle(_parent.boidGroupRange, "Group Range Circle"); + 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 - // Draw FOV Line - DrawArcCentered(_parent.boidGroupRange, Util.Vector2ToAngle(_velocity), - _parent.boidFOV, "FOV Arc"); + 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 + 180); + } } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index 68aece8..3e15fa6 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -97,6 +97,13 @@ public class BoidController : MonoBehaviour { 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; + + Time.timeScale = 0.3f; + AddBoids(boidCount); } From 7bc306a7f6a9d8a63e48cd3220040c27c3a2a601 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 20:56:13 -0500 Subject: [PATCH 18/19] use DestroyImmediate to fix pause Boid FOV edits creating duplicate LineRenderers, fix arc calculations and rotate correctly, FOV arc finally 'fixed' properly (again), fix XML docs/comments --- Boids/Assets/Scripts/Boid.cs | 4 ++-- Boids/Assets/Scripts/ShapeDraw.cs | 23 ++++++++--------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index 6da9e05..add2380 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -231,7 +231,7 @@ public class Boid : MonoBehaviour { // Destroy Line Renderers (and child GameObjects) foreach (Transform child in transform) - Destroy(child.gameObject); + DestroyImmediate(child.gameObject); Array.Clear(_lineRenderers, 0, _lineRenderers.Length); } @@ -265,7 +265,7 @@ public class Boid : MonoBehaviour { 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 + 180); + _lineRenderers[2].transform.Rotate(0, 0, _parent.boidFOV / 2f); } } } \ No newline at end of file diff --git a/Boids/Assets/Scripts/ShapeDraw.cs b/Boids/Assets/Scripts/ShapeDraw.cs index b5502f1..9707b03 100644 --- a/Boids/Assets/Scripts/ShapeDraw.cs +++ b/Boids/Assets/Scripts/ShapeDraw.cs @@ -3,7 +3,7 @@ /// /// A simple static utility class that assists with drawing shapes using the LineRenderer class. /// -public class ShapeDraw { +public static class ShapeDraw { public static float CircleWidth = 1f; public static float ArcWidth = 1f; public static int CircleVertexCount = 360; @@ -12,12 +12,12 @@ public class ShapeDraw { /// /// Draw a Arc aimed straight up with a certain angle width and radius. - /// Use to point the Arc at a certain direction. + /// This Arc is not direct at any specific angle and start from 0 degrees and ends at angle degrees. + /// You should rotate the LineRenderer to direct it at a specific point. /// /// The LineRenderer to draw the Arc upon. - /// Angle of the Arc + /// Angle (width) of the Arc /// Radius of the Arc - /// public static void DrawArc(LineRenderer lineRenderer, float angle, float radius) { // Setup LineRenderer properties lineRenderer.useWorldSpace = false; @@ -29,9 +29,9 @@ public class ShapeDraw { var pointCount = ArcVertexCount + 1; var points = new Vector3[pointCount + 2]; + // Generate all points for (int i = 0; i < pointCount; i++) { - // Magic '180 - angle' - var rad = Mathf.Deg2Rad * Mathf.LerpAngle(0, angle, i / (float) pointCount); + var rad = Mathf.Deg2Rad * Mathf.Lerp(0, angle, (float) i / pointCount); points[i + 1] = new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0) * radius; } @@ -45,7 +45,8 @@ public class ShapeDraw { /// /// Draw a Circle with a specific radius and number of vertexes (detail level) /// - /// + /// The LineRenderer to draw the Circle upon + /// Radius of the Circle public static void DrawCircle(LineRenderer lineRenderer, float radius) { // Setup LineRenderer properties lineRenderer.useWorldSpace = false; @@ -64,12 +65,4 @@ public class ShapeDraw { // Add points to LineRenderer lineRenderer.SetPositions(points); } - - /// - /// - /// - /// - public static void RotateLineRenderer(LineRenderer lineRenderer) { - - } } \ No newline at end of file From cddacb0efa004553974eaf876575855c69dea0d4 Mon Sep 17 00:00:00 2001 From: Xevion Date: Fri, 5 Jun 2020 21:44:10 -0500 Subject: [PATCH 19/19] remove TimeScale, fix DisableFocusing concerning LineRenderer array --- Boids/Assets/Scripts/Boid.cs | 8 +++++--- Boids/Assets/Scripts/BoidController.cs | 2 -- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Boids/Assets/Scripts/Boid.cs b/Boids/Assets/Scripts/Boid.cs index add2380..20c4082 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -230,9 +230,11 @@ public class Boid : MonoBehaviour { // Destroy Line Renderers (and child GameObjects) - foreach (Transform child in transform) - DestroyImmediate(child.gameObject); - Array.Clear(_lineRenderers, 0, _lineRenderers.Length); + for (int i = 0; i < _lineRenderers.Length; i++) { + _lineRenderers[i].positionCount = 0; + DestroyImmediate(_lineRenderers[i].gameObject); + _lineRenderers[i] = null; + } } /// diff --git a/Boids/Assets/Scripts/BoidController.cs b/Boids/Assets/Scripts/BoidController.cs index 3e15fa6..1b7b711 100644 --- a/Boids/Assets/Scripts/BoidController.cs +++ b/Boids/Assets/Scripts/BoidController.cs @@ -102,8 +102,6 @@ public class BoidController : MonoBehaviour { ShapeDraw.CircleVertexCount = circleVertexCount; // ShapeDraw.ArcVertexCount = arcVertexCount; - Time.timeScale = 0.3f; - AddBoids(boidCount); }