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/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/Scripts/BoidControllerEditor.cs b/Boids/Assets/Editor/BoidControllerEditor.cs similarity index 50% rename from Boids/Assets/Scripts/BoidControllerEditor.cs rename to Boids/Assets/Editor/BoidControllerEditor.cs index 1ff1fbf..eb2050f 100644 --- a/Boids/Assets/Scripts/BoidControllerEditor.cs +++ b/Boids/Assets/Editor/BoidControllerEditor.cs @@ -1,12 +1,12 @@ -#if UNITY_EDITOR -using UnityEditor; +using UnityEditor; 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; + // Boid Count update EditorGUI.BeginChangeCheck(); controller.boidCount = EditorGUILayout.IntSlider("Boid Count", controller.boidCount, 1, 500); @@ -20,31 +20,47 @@ 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); - controller.boidSeparationRange = EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f); + 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, 200f); - + 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); + redraw = redraw || EditorGUI.EndChangeCheck(); + // 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); - 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); 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); - controller.circleWidth = EditorGUILayout.Slider("Circle Line Width", controller.circleWidth, 0.01f, 1f); + 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); + 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 +} \ 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 diff --git a/Boids/Assets/Editor/BoidEditor.cs b/Boids/Assets/Editor/BoidEditor.cs new file mode 100644 index 0000000..6686879 --- /dev/null +++ b/Boids/Assets/Editor/BoidEditor.cs @@ -0,0 +1,24 @@ +using UnityEditor; +using UnityEngine; + +[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}"); + + 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/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/Resources/Icons/banner.psd.meta b/Boids/Assets/Resources/Icons/banner.psd.meta index fd908ea..5273e87 100644 --- a/Boids/Assets/Resources/Icons/banner.psd.meta +++ b/Boids/Assets/Resources/Icons/banner.psd.meta @@ -84,7 +84,7 @@ TextureImporter: secondaryTextures: [] spritePackingTag: pSDRemoveMatte: 0 - pSDShowRemoveMatteOption: 1 + pSDShowRemoveMatteOption: 0 userData: assetBundleName: assetBundleVariant: 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.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/Boid.cs b/Boids/Assets/Scripts/Boid.cs index d31ece5..20c4082 100644 --- a/Boids/Assets/Scripts/Boid.cs +++ b/Boids/Assets/Scripts/Boid.cs @@ -1,27 +1,26 @@ 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 +// 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 Renderer[] _renderers; [NonSerialized] private Vector2 _centeringVelocity; - [NonSerialized] private int _latestNeighborhoodCount = 0; + [NonSerialized] public int latestNeighborhoodCount = 0; + [NonSerialized] public List latestNeighborhood; [NonSerialized] private BoidController _parent; - [NonSerialized] public bool isFocused = false; + [NonSerialized] public bool _isFocused = false; + [NonSerialized] private LineRenderer[] _lineRenderers; + 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 @@ -29,7 +28,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) { @@ -40,7 +39,11 @@ 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; + + // 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) { @@ -169,64 +172,102 @@ 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) { + // Distance Check + if (boid == this || Vector2.Distance(this._position, boid._position) > radius) + continue; + + // FOV Check + 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) + continue; + + } + + // Boid passed all checks, add to local Flock list + flock.Add(boid); + } + + return flock; } // 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"); + if (_isFocused) { + Debug.LogWarning($"enableFocusing called on previously focused Boid ({transform.name})"); return; } - isFocused = true; + _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; - // Add a LineRenderer for Radius Drawing - DrawCircle(_parent.boidSeparationRange, "Separation Range Circle"); - DrawCircle(_parent.boidGroupRange, "Group Range Circle"); + // Draw all focus related elements + Draw(false); } // Disable focusing, removing LineRenderers and resetting color public void DisableFocusing() { - isFocused = false; + _isFocused = false; // 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); + for (int i = 0; i < _lineRenderers.Length; i++) { + _lineRenderers[i].positionCount = 0; + DestroyImmediate(_lineRenderers[i].gameObject); + _lineRenderers[i] = null; + } } - private void DrawCircle(float radius, string childName) { - // Create a new child GameObject to hold the LineRenderer Component + /// + /// 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); + // Make object a child of Boid, set position as such child.transform.SetParent(transform); child.transform.position = transform.position; - var line = child.AddComponent(); + // add and return LineRenderer component + return child.AddComponent(); + } - _parent.circleVertexCount = 360; + public void Draw(bool redraw) { + // Clear positions when redrawing + if(redraw) + foreach (LineRenderer lineRenderer in _lineRenderers) + lineRenderer.positionCount = 0; + + // Add a LineRenderer for Radius Drawing + 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 - // 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); + 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); } - - // 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 211cfc5..1b7b711 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 { @@ -29,14 +28,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 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 = 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; public Boid focusedBoid; // A focused Boid has special rendering @@ -76,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.LookAtDirect(focusedBoid.transform.position, Quaternion.identity); + #endif } private void Start() { @@ -89,6 +97,11 @@ 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; + AddBoids(boidCount); } diff --git a/Boids/Assets/Scripts/ShapeDraw.cs b/Boids/Assets/Scripts/ShapeDraw.cs new file mode 100644 index 0000000..9707b03 --- /dev/null +++ b/Boids/Assets/Scripts/ShapeDraw.cs @@ -0,0 +1,68 @@ +using UnityEngine; + +/// +/// 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; + + + /// + /// 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. + /// You should rotate the LineRenderer to direct it at a specific point. + /// + /// The LineRenderer to draw the Arc upon. + /// 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; + 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]; + + // Generate all points + for (int i = 0; i < pointCount; i++) { + var rad = Mathf.Deg2Rad * Mathf.Lerp(0, angle, (float) i / 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); + } + + /// + /// 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; + 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); + } +} \ 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 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/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 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}