From 1dd037839e70c40cc368402c6026d7669e50eb82 Mon Sep 17 00:00:00 2001 From: Xevion Date: Sat, 16 May 2020 18:22:59 -0500 Subject: [PATCH] Major work with new Boid prefrab, configuring rules and attempt at camera wrapping - getting close to working prototype --- Assets/Boid.cs | 105 ++++++++++++++++++++++++++++++++------- Assets/Boid.prefab | 61 +++++++++++++++++++++++ Assets/Boid.prefab.meta | 7 +++ Assets/BoidController.cs | 51 ++++++++++++------- Packages/manifest.json | 1 - 5 files changed, 189 insertions(+), 36 deletions(-) create mode 100644 Assets/Boid.prefab create mode 100644 Assets/Boid.prefab.meta diff --git a/Assets/Boid.cs b/Assets/Boid.cs index 82c05bd..b6b7b39 100644 --- a/Assets/Boid.cs +++ b/Assets/Boid.cs @@ -1,50 +1,119 @@ using System.Collections.Generic; using UnityEngine; +using UnityEngine.Analytics; // Boids are represented by a moving, rotating triangle. // Boids should communicate with sibling Boids public class Boid : MonoBehaviour { - public Vector2 velocity = Vector2.zero; + public Vector2 position = Vector2.zero; + public Vector2 velocity; + private Renderer[] _renderers; + bool _isWrappingX = false; + bool _isWrappingY = false; + Camera _cam; + Vector3 _viewportPosition; void Start() { - velocity = Vector2.one; + velocity = new Vector2(0.03f * Random.value < 0.5 ? 1 : -1, 0.03f * Random.value < 0.5 ? 1 : -1); + _renderers = GetComponents(); + _cam = Camera.main; + _viewportPosition = _cam.WorldToViewportPoint(transform.position); } - // Returns the next position the Boid will be moving to - public Vector2 NextPosition(List boids, float[] magnitudes) { - // Find the local flock - List flock = GetFlock(boids, 5); - - // Calculate all offsets and multiple by magnitudes given - Vector2 r1 = Rule1(flock) * magnitudes[0]; - Vector2 r2 = Rule2(flock) * magnitudes[1]; - Vector2 r3 = Rule3(flock) * magnitudes[2]; + 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)); + ScreenWrap(); + } - return transform.position + (Vector3) (r1 + r2 + r3); + bool CheckRenderers() { + foreach (var renderer in _renderers) { + // If at least one render is visible, return true + if (renderer.isVisible) { + return true; + } + } + + // Otherwise, the object is invisible + return false; + } + + void ScreenWrap() { + var isVisible = CheckRenderers(); + + if (isVisible) { + _isWrappingX = false; + _isWrappingY = false; + return; + } + + if (_isWrappingX && _isWrappingY) { + return; + } + var newPosition = transform.position; + + if (!_isWrappingX && (_viewportPosition.x > 1 || _viewportPosition.x < 0)) { + newPosition.x = -newPosition.x; + _isWrappingX = true; + } + + if (!_isWrappingY && (_viewportPosition.y > 1 || _viewportPosition.y < 0)) { + newPosition.y = -newPosition.y; + _isWrappingY = true; + } + + transform.position = newPosition; + } + + public Vector2 NextPosition(List boids, float[] magnitudes) { + // Acquires all + List flock = GetFlock(boids, 20); + + if (flock.Count > 0) { + // Calculate all offsets and multiple by magnitudes given + Vector2 r1 = Rule1(flock) * magnitudes[0]; + Vector2 r2 = Rule2(flock) * magnitudes[1]; + Vector2 r3 = Rule3(flock) * magnitudes[2]; + velocity += r1 + r2 + r3; + } + + LimitVelocity(); + + return position + velocity; + } + + void LimitVelocity() { + if (velocity.magnitude > 2f) { + velocity = (velocity / velocity.magnitude) * 2f; + } } // Cohesion: Steer towards center of mass of flock Vector2 Rule1(List flock) { Vector2 center = Vector2.zero; foreach (Boid boid in flock) - center += (Vector2) boid.transform.position; + center += boid.position; center /= flock.Count; - return (center - (Vector2) transform.position) / 100; + return (center - this.position) / 100; } // Separation: Steer to avoid other Boids within flock Vector2 Rule2(List flock) { Vector2 c = Vector2.zero; foreach (Boid boid in flock) { - Vector2 diff = boid.transform.position - transform.position; + Vector2 diff = boid.position - this.position; if (diff.magnitude < 5) c -= diff; } + return c; } // Alignment: Steer to align with the average heading of the flock Vector3 Rule3(List flock) { + if (flock.Count == 0) + return Vector2.zero; + Vector2 perceived = Vector2.zero; foreach (Boid boid in flock) perceived += boid.velocity; @@ -55,9 +124,9 @@ public class Boid : MonoBehaviour { // Returns a list of boids within a certain radius of the Boid, representing it's local 'flock' List GetFlock(List boids, float radius) { List flock = new List(); - foreach(Boid boid in boids) - if(boid != this && Vector2.Distance(transform.position, boid.transform.position) <= radius) + foreach (Boid boid in boids) + if (boid != this && Vector2.Distance(this.position, boid.position) <= radius) flock.Add(boid); return flock; } -} +} \ No newline at end of file diff --git a/Assets/Boid.prefab b/Assets/Boid.prefab new file mode 100644 index 0000000..e6fab35 --- /dev/null +++ b/Assets/Boid.prefab @@ -0,0 +1,61 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1737515784064720040 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1737515784064720086} + - component: {fileID: 1737515784064720041} + - component: {fileID: 1737515784064720087} + m_Layer: 0 + m_Name: Boid + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1737515784064720086 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1737515784064720040} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1737515784064720041 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1737515784064720040} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 39c543193832a9745a8985fb0e672377, type: 3} + m_Name: + m_EditorClassIdentifier: + fillColor: {r: 0, g: 0, b: 1, a: 1} +--- !u!114 &1737515784064720087 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1737515784064720040} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8fa9bbc6d9eb4c368be190feba139e7c, type: 3} + m_Name: + m_EditorClassIdentifier: + position: {x: 0, y: 0} + velocity: {x: 0.05, y: 0.05} diff --git a/Assets/Boid.prefab.meta b/Assets/Boid.prefab.meta new file mode 100644 index 0000000..a906512 --- /dev/null +++ b/Assets/Boid.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 23e1eaaf69d4ef342ac3ef9590f6c642 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/BoidController.cs b/Assets/BoidController.cs index e3486d0..275f68c 100644 --- a/Assets/BoidController.cs +++ b/Assets/BoidController.cs @@ -1,34 +1,51 @@ -using System.Collections; -using System.Collections.Generic; +using System.Collections.Generic; using UnityEngine; +using Random = UnityEngine.Random; public class BoidController : MonoBehaviour { // Controller Attributes - public Rect space; - + public Rect space = new Rect(new Vector2(0, 0), new Vector2(24000, 14000)); + // Swarm Attributes - public int boidCount = 1000; + public int boidCount = 50; public float boidGroupRange = 1.0f; - + // Bias changes how different rules influence individual Boids more or less public float separationBias = 1.0f; public float alignmentBias = 1.0f; public float cohesionBias = 1.0f; - - private List _boids = new List(); - + + public GameObject boidObject; + + public List boids = new List(); + + private void OnDrawGizmos() { + Gizmos.DrawWireCube(space.center, space.size); + } + void Start() { - for(int i = 0; i < boidCount; i++) - _boids.Add(new Boid(Vector2.zero, new Vector2(1, 1))); + for (int i = 0; i < boidCount; i++) { + var position = new Vector2(Random.Range(-15, 15), Random.Range(-15, 15)); + var boid = Instantiate(boidObject, position, Quaternion.identity); + + boid.transform.parent = transform; + boids.Add(boid.GetComponent()); + boids[boids.Count - 1].position = position; + } } void Update() { - float[] magnitudes = new float[] {cohesionBias, separationBias, alignmentBias}; + // foreach (Boid boid in boids) { + // if (!space.Contains(boid.position)) + // boid.position = transform.position; + // } + + float[] magnitudes = {cohesionBias, separationBias, alignmentBias}; // Update all Boid positions - foreach (Boid boid in _boids) { - boid.SetPosition(boid.NextPosition(_boids, magnitudes)); + foreach (Boid boid in boids) { + Vector2 next = boid.NextPosition(boids, magnitudes); + boid.position = next; + boid.transform.position = new Vector3(next.x, next.y, 0); } } - - -} +} \ No newline at end of file diff --git a/Packages/manifest.json b/Packages/manifest.json index b319b7e..324d1ed 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,6 +1,5 @@ { "dependencies": { - "com.akb.knn": "file:F:/Programming/Unity/KNN", "com.unity.ads": "2.0.8", "com.unity.analytics": "3.3.2", "com.unity.collab-proxy": "1.2.16",