update Boid velocity to angle and angle difference methods for FOV detection, finished working FOV detection

This commit is contained in:
Xevion
2020-06-05 17:53:55 -05:00
parent 8ee9f33082
commit f6dd8f6c2a
2 changed files with 38 additions and 26 deletions

View File

@@ -1,18 +1,20 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEditor;
using UnityEngine; using UnityEngine;
// Boids are represented by a moving, rotating triangle. // Boids are represented by a moving, rotating triangle.
// Boids should communicate with sibling Boids via the parental BoidController object // Boids should communicate with sibling Boids via the parental BoidController object
public class Boid : MonoBehaviour { public class Boid : MonoBehaviour {
[NonSerialized] private Vector2 _position = Vector2.zero; [NonSerialized] private Vector2 _position = Vector2.zero;
[NonSerialized] private Vector2 _velocity; [NonSerialized] public Vector2 _velocity;
[NonSerialized] private bool _isWrappingX = false; [NonSerialized] private bool _isWrappingX = false;
[NonSerialized] private bool _isWrappingY = false; [NonSerialized] private bool _isWrappingY = false;
[NonSerialized] private Vector2 _centeringVelocity; [NonSerialized] private Vector2 _centeringVelocity;
[NonSerialized] public int latestNeighborhoodCount = 0; [NonSerialized] public int latestNeighborhoodCount = 0;
[NonSerialized] public List<Boid> latestNeighborhood;
[NonSerialized] private BoidController _parent; [NonSerialized] private BoidController _parent;
[NonSerialized] private bool _isFocused = false; [NonSerialized] public bool _isFocused = false;
private void Start() { private void Start() {
_parent = transform.parent _parent = transform.parent
@@ -37,6 +39,10 @@ public class Boid : MonoBehaviour {
List<Boid> flock = _parent.localFlocks ? GetFlock(_parent.boids, _parent.boidGroupRange) : _parent.boids; List<Boid> 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 // Calculate all offsets and multiple by magnitudes given
if (flock.Count > 0) { if (flock.Count > 0) {
if (_parent.enableCohesion) if (_parent.enableCohesion)
@@ -173,10 +179,13 @@ public class Boid : MonoBehaviour {
// FOV Check // FOV Check
if (_parent.enableFOVChecks) { if (_parent.enableFOVChecks) {
float angle1 = Mathf.Rad2Deg * -Mathf.Atan2(_velocity.x, _velocity.y); float angle1 = Util.Vector2ToAngle(_velocity); // Current Heading
float angle2 = Mathf.Rad2Deg * -Mathf.Atan2(boid._velocity.x, boid._velocity.y); float angle2 = Util.AngleBetween(transform.position, boid.transform.position); // Angle between Boid and other Boid
if (Mathf.Abs(angle2 - angle1) > _parent.boidFOV / 2)
// Outside of FOV range, skip
if (Mathf.Abs(Mathf.DeltaAngle(angle1, angle2)) > _parent.boidFOV / 2)
continue; continue;
} }
flock.Add(boid); flock.Add(boid);
@@ -224,7 +233,7 @@ public class Boid : MonoBehaviour {
DrawCircle(_parent.boidGroupRange, "Group Range Circle"); DrawCircle(_parent.boidGroupRange, "Group Range Circle");
// Draw FOV Line // Draw FOV Line
DrawArcCentered((_parent.boidSeparationRange + _parent.boidGroupRange) / 2f, transform.eulerAngles.z, DrawArcCentered(_parent.boidGroupRange, Util.Vector2ToAngle(_velocity),
_parent.boidFOV, "FOV Arc"); _parent.boidFOV, "FOV Arc");
} }
@@ -254,7 +263,8 @@ public class Boid : MonoBehaviour {
} }
private void DrawArcCentered(float radius, float centerAngle, float angleWidth, string childName) { 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) { private void DrawArc(float radius, float from, float to, string childName) {
@@ -275,10 +285,11 @@ public class Boid : MonoBehaviour {
// Calculate points for circle // Calculate points for circle
var pointCount = vertexCount + 1; var pointCount = vertexCount + 1;
var points = new Vector3[pointCount + 2]; var points = new Vector3[pointCount + 2];
for (int i = 0; i < pointCount; i++) { for (int i = 0; i < pointCount; i++) {
// Magic '180 - angle' // Magic '180 - angle'
var rad = Mathf.Deg2Rad * (180 - Mathf.LerpAngle(from, to, i / (float) pointCount)); var rad = Mathf.Deg2Rad * Mathf.LerpAngle(from, to, i / (float) pointCount);
points[i + 1] = new Vector3(Mathf.Sin(rad) * radius, Mathf.Cos(rad) * radius, 0); points[i + 1] = new Vector3(Mathf.Sin(rad), Mathf.Cos(rad), 0) * radius;
} }
points[0] = new Vector3(0, 0, 0); points[0] = new Vector3(0, 0, 0);

View File

@@ -6,13 +6,13 @@ public class Util {
var sa = Mathf.Sin(a); var sa = Mathf.Sin(a);
var rx = v.x * ca - v.y * sa; 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 // Returns a velocity (Vector2) at a random angle with a specific overall magnitude
public static Vector2 GetRandomVelocity(float magnitude) { public static Vector2 GetRandomVelocity(float magnitude) {
var vector = new Vector2(magnitude, 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) { public static Vector2 MaxVelocity(Vector2 v, float max) {
@@ -27,24 +27,25 @@ public class Util {
return v; return v;
} }
public static Vector2 AbsVector(Vector2 vector) { public static float Vector2ToAngle(Vector2 velocity) {
return new Vector2(vector.x, vector.y); float result = Mathf.Rad2Deg * Mathf.Atan2(velocity.y, velocity.x);
} return (result < 0) ? (360f + result) : result;
} }
public class Scale { public static float AngleBetween(Vector2 from, Vector2 to) {
private Vector2 _original; Vector2 diff = to - from;
private Vector2 _new; float result = Mathf.Rad2Deg * Mathf.Atan2(diff.y, diff.x);
private Vector2 _ratio; return (result < 0) ? (360f + result) : result;
}
public float X => _ratio.x; public static float AngleDifference(float angle1, float angle2) {
public float Y => _ratio.y; 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 static float AddAngle(float angle, float add) {
float result = angle + add;
public Scale(Vector2 original, Vector2 resized) { if (result > 360) return result - 360;
_original = original; if (result < 0) return 360 + result;
_new = resized; return result;
_ratio = _original / _new;
} }
} }