mirror of
https://github.com/Xevion/Boids.git
synced 2025-12-10 10:06:39 -06:00
Added new Editor for controlling Boid count, new methods for adding.removing Boids
This commit is contained in:
@@ -15,6 +15,7 @@ public class Boid : MonoBehaviour {
|
||||
[NonSerialized] private bool _isWrappingY = false;
|
||||
[NonSerialized] private Renderer[] _renderers;
|
||||
[NonSerialized] private Vector2 _centeringVelocity;
|
||||
[NonSerialized] private int _latestNeighborhoodCount = 0;
|
||||
private BoidController _parent;
|
||||
|
||||
void Start() {
|
||||
@@ -26,14 +27,10 @@ public class Boid : MonoBehaviour {
|
||||
transform.name = $"Boid {transform.GetSiblingIndex()}"; // Name the Game Object so Boids can be tracked somewhat
|
||||
}
|
||||
|
||||
void OnDrawGizmos() {
|
||||
// Handles.color = _isWrappingX || _isWrappingY ? Color.red : Color.white;
|
||||
// Vector3 viewportPosition = _parent.cam.WorldToViewportPoint(transform.position);
|
||||
// Handles.Label(transform.position,
|
||||
// $"{(Vector2) viewportPosition} {(_isWrappingX ? "Y" : "N")} {(_isWrappingY ? "Y" : "N")}");
|
||||
var transform_ = transform;
|
||||
Handles.Label(transform_.position, $"{transform_.name}");
|
||||
}
|
||||
void OnDrawGizmos() {
|
||||
var transform_ = transform;
|
||||
Handles.Label(transform_.position, $"{transform_.name} {_latestNeighborhoodCount}");
|
||||
}
|
||||
|
||||
void Update() {
|
||||
// Updates the rotation of the object based on the Velocity
|
||||
@@ -47,6 +44,7 @@ public class Boid : MonoBehaviour {
|
||||
}
|
||||
else {
|
||||
List<Boid> flock = _parent.localFlocks ? GetFlock(_parent.boids, _parent.boidGroupRange) : _parent.boids;
|
||||
_latestNeighborhoodCount = flock.Count;
|
||||
|
||||
// Calculate all offsets and multiple by magnitudes given
|
||||
if (flock.Count > 0) {
|
||||
@@ -70,7 +68,7 @@ public class Boid : MonoBehaviour {
|
||||
if (!_parent.Space.Contains(_position)) {
|
||||
// Activate Wrap, Move
|
||||
Vector2 newPosition = transform.position;
|
||||
Vector3 viewportPosition = _parent.cam.WorldToViewportPoint(newPosition);
|
||||
Vector3 viewportPosition = _parent.Cam.WorldToViewportPoint(newPosition);
|
||||
|
||||
if (!_isWrappingX && (viewportPosition.x > 1 || viewportPosition.x < 0)) {
|
||||
newPosition.x = -newPosition.x;
|
||||
@@ -101,6 +99,7 @@ public class Boid : MonoBehaviour {
|
||||
_centeringVelocity = Util.LimitVelocity(_parent.Space.center - _position, _parent.boidVelocityLimit / 2.0f);
|
||||
}
|
||||
|
||||
// Returns a velocity (Vector2) at a random angle with a specific overall magnitude
|
||||
Vector2 GetRandomVelocity(float magnitude) {
|
||||
Vector2 vector = new Vector2(magnitude, magnitude);
|
||||
return Util.RotateBy(vector, Random.Range(0, 180));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Debug = System.Diagnostics.Debug;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
public class BoidController : MonoBehaviour {
|
||||
@@ -20,43 +21,43 @@ public class BoidController : MonoBehaviour {
|
||||
public float cohesionBias = 0.05f;
|
||||
public bool localFlocks = true;
|
||||
|
||||
// Boid Object Prefab
|
||||
public GameObject boidObject;
|
||||
|
||||
// Boid Objects for Updates
|
||||
[NonSerialized] [HideInInspector] public List<Boid> boids = new List<Boid>();
|
||||
|
||||
// Used for wrapping
|
||||
public Camera cam;
|
||||
public Boid focusedBoid; // A focused Boid has special rendering
|
||||
public GameObject boidObject; // Boid Object Prefab
|
||||
[NonSerialized] public List<Boid> boids = new List<Boid>(); // Boid Objects for Updates
|
||||
[NonSerialized] public Camera Cam; // Used for wrapping detection
|
||||
|
||||
private void OnDrawGizmos() {
|
||||
// Draw a Wire Cube for the Rectangle Area
|
||||
Gizmos.DrawWireCube(Space.center, Space.size);
|
||||
|
||||
|
||||
if (Cam == null)
|
||||
return;
|
||||
|
||||
// Draw a Wire Cube for the Cam's Viewport Area
|
||||
Vector3 screenBottomLeft = cam.ViewportToWorldPoint(new Vector3(0, 0, transform.position.z));
|
||||
Vector3 screenTopRight = cam.ViewportToWorldPoint(new Vector3(1, 1, transform.position.z));
|
||||
var position = transform.position;
|
||||
Vector3 screenBottomLeft = Cam.ViewportToWorldPoint(new Vector3(0, 0, position.z));
|
||||
Vector3 screenTopRight = Cam.ViewportToWorldPoint(new Vector3(1, 1, position.z));
|
||||
var screenWidth = screenTopRight.x - screenBottomLeft.x;
|
||||
var screenHeight = screenTopRight.y - screenBottomLeft.y;
|
||||
Gizmos.DrawWireCube(cam.transform.position, new Vector3(screenWidth, screenHeight, 1));
|
||||
Gizmos.DrawWireCube(Cam.transform.position, new Vector3(screenWidth, screenHeight, 1));
|
||||
}
|
||||
|
||||
private void Start() {
|
||||
// Setup Camera
|
||||
cam = Camera.main;
|
||||
Cam = Camera.main;
|
||||
|
||||
// Size the Rectangle based on the Camera's Orthographic View
|
||||
float height = 2f * cam.orthographicSize;
|
||||
Vector2 size = new Vector2(height * cam.aspect, height);
|
||||
float height = 2f * Cam.orthographicSize;
|
||||
Vector2 size = new Vector2(height * Cam.aspect, height);
|
||||
Space = new Rect((Vector2) transform.position - size / 2, size);
|
||||
|
||||
// Add in Boid Objects / Spawn Boid Prefabs
|
||||
for (int i = 0; i < boidCount; i++) {
|
||||
// Generate a new position within the Rect boundaries (minus a little)
|
||||
var position = new Vector2(
|
||||
Random.Range(-Space.size.x, Space.size.x) / 2 * 0.95f,
|
||||
Random.Range(-Space.size.y, Space.size.y) / 2 * 0.95f);
|
||||
// Spawn a new Boid prefab
|
||||
AddBoids(boidCount);
|
||||
}
|
||||
|
||||
public void AddBoids(int n) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
// Instantiate a Boid prefab within the boundaries randomly
|
||||
Vector2 position = RandomPosition() * 0.95f;
|
||||
GameObject boid = Instantiate(boidObject, position, Quaternion.identity);
|
||||
|
||||
// Set parent, add Boid component to Boids list
|
||||
@@ -64,4 +65,32 @@ public class BoidController : MonoBehaviour {
|
||||
boids.Add(boid.GetComponent<Boid>());
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveBoids(int n) {
|
||||
print($"Removing {n} boids");
|
||||
while (n-- > 0 && boids.Count >= 1) {
|
||||
int index = Random.Range(0, boids.Count - 1);
|
||||
|
||||
// Only remove the focused Boid if it is the last one
|
||||
if (boids[index] == focusedBoid)
|
||||
if (boids.Count == 1)
|
||||
RemoveBoid(1);
|
||||
else
|
||||
n++;
|
||||
else
|
||||
RemoveBoid(index);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveBoid(int index) {
|
||||
Boid boid = boids[index];
|
||||
boids.RemoveAt(index);
|
||||
Destroy(boid.transform.gameObject);
|
||||
}
|
||||
|
||||
private Vector2 RandomPosition() {
|
||||
return new Vector2(
|
||||
Random.Range(-Space.size.x, Space.size.x) / 2,
|
||||
Random.Range(-Space.size.y, Space.size.y) / 2);
|
||||
}
|
||||
}
|
||||
57
Boids/Assets/BoidController.prefab
Normal file
57
Boids/Assets/BoidController.prefab
Normal file
@@ -0,0 +1,57 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &4181400676305357553
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4181400676305357555}
|
||||
- component: {fileID: 4181400676305357552}
|
||||
m_Layer: 0
|
||||
m_Name: BoidController
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4181400676305357555
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4181400676305357553}
|
||||
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 &4181400676305357552
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4181400676305357553}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 7d72224fef7a4fb4a998b0980fe0eb77, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
boidCount: 1
|
||||
boidGroupRange: 4.57
|
||||
boidStartVelocity: 0.05
|
||||
boidVelocityLimit: 0.5
|
||||
separationRange: 2.5
|
||||
separationBias: 0.05
|
||||
alignmentBias: 0.5
|
||||
cohesionBias: 0.01
|
||||
localFlocks: 1
|
||||
focusedBoid: {fileID: 0}
|
||||
boidObject: {fileID: 1737515784064720040, guid: 23e1eaaf69d4ef342ac3ef9590f6c642,
|
||||
type: 3}
|
||||
7
Boids/Assets/BoidController.prefab.meta
Normal file
7
Boids/Assets/BoidController.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79543cb69dabd5846a1789cccbdeefd8
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
23
Boids/Assets/BoidControllerEditor.cs
Normal file
23
Boids/Assets/BoidControllerEditor.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(BoidController))]
|
||||
public class BoidControllerEditor : Editor {
|
||||
public override void OnInspectorGUI() {
|
||||
BoidController controller = (BoidController) target;
|
||||
|
||||
// Boid Count update
|
||||
EditorGUI.BeginChangeCheck();
|
||||
controller.boidCount = EditorGUILayout.IntSlider("Boid Count", controller.boidCount, 1, 500);
|
||||
if (EditorGUI.EndChangeCheck() && Application.isPlaying) {
|
||||
int diff = controller.boidCount - controller.boids.Count;
|
||||
Debug.Log($"Difference: {diff}");
|
||||
if (diff > 1)
|
||||
controller.AddBoids(diff);
|
||||
else if (diff < 0)
|
||||
controller.RemoveBoids(Mathf.Abs(diff));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
3
Boids/Assets/BoidControllerEditor.cs.meta
Normal file
3
Boids/Assets/BoidControllerEditor.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ec8daef16a2459989f9d8b81bb248ea
|
||||
timeCreated: 1589767516
|
||||
Reference in New Issue
Block a user