Moved all scripts into Scripts folder, project organization, more comments, other stuff (?)

This commit is contained in:
Xevion
2020-05-18 21:26:53 -05:00
parent 5558326633
commit b8abb9e4d7
24 changed files with 20 additions and 1103 deletions

View File

@@ -1,171 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEditor;
using UnityEngine;
using Random = UnityEngine.Random;
// Boids are represented by a moving, rotating triangle.
// Boids should communicate with sibling Boids
public class Boid : MonoBehaviour {
[NonSerialized] private Vector2 _position = Vector2.zero;
[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;
private BoidController _parent;
void Start() {
_parent = transform.parent
.GetComponent<BoidController>(); // Parent used to perform physics math without caching
_renderers = transform.GetComponents<Renderer>(); // Acquire Renderer(s) to check for Boid visibility
_velocity = 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
}
// void OnDrawGizmos() {
// var transform_ = transform;
// Handles.Label(transform_.position, $"{transform_.name} {_latestNeighborhoodCount}");
// }
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));
// Skip Flock Calculations if wrapping in progress
if (_isWrappingX || _isWrappingY) {
UpdateCenteringVelocity();
_position += _centeringVelocity;
transform.position = _position;
}
else {
List<Boid> flock = _parent.localFlocks ? GetFlock(_parent.boids, _parent.boidGroupRange) : _parent.boids;
_latestNeighborhoodCount = flock.Count;
// Calculate all offsets and multiple by magnitudes given
Vector2 r1, r2, r3, r4;
r4 = _parent.Boundary.Contains(_position) ? Vector2.zero : RuleBound() * _parent.boundaryBias;
if (flock.Count > 0) {
r1 = Rule1(flock) * _parent.cohesionBias;
r2 = Rule2(flock) * _parent.separationBias;
r3 = Rule3(flock) * _parent.alignmentBias;
_velocity += r1 + r2 + r3 + r4;
}
else {
_velocity += r4;
}
// Limit the Velocity Vector to a certain Magnitude
_velocity = Util.LimitVelocity(_velocity, _parent.boidVelocityLimit);
_position += _velocity;
transform.position = new Vector3(_position.x, _position.y, 0);
}
if (_parent.edgeWrapping)
Wrapping();
}
private void Wrapping() {
if (!_parent.Space.Contains(_position)) {
// Activate Wrap, Move
Vector2 newPosition = transform.position;
Vector3 viewportPosition = _parent.Cam.WorldToViewportPoint(newPosition);
if (!_isWrappingX && (viewportPosition.x > 1 || viewportPosition.x < 0)) {
newPosition.x = -newPosition.x;
_isWrappingX = true;
UpdateCenteringVelocity();
}
if (!_isWrappingY && (viewportPosition.y > 1 || viewportPosition.y < 0)) {
newPosition.y = -newPosition.y;
_isWrappingY = true;
UpdateCenteringVelocity();
}
transform.position = newPosition;
_position = newPosition;
}
else {
// Within the rectangle again
_isWrappingX = false;
_isWrappingY = false;
}
}
// When Wrapping, this Velocity directs the Boid to the center of the Rectangle
private void UpdateCenteringVelocity() {
_centeringVelocity = Util.RotateBy(new Vector2(_parent.boidVelocityLimit, _parent.boidVelocityLimit),
Vector2.Angle(_position, _parent.Space.center));
_centeringVelocity = Util.LimitVelocity(_parent.Space.center - _position, _parent.boidVelocityLimit / 2.0f);
}
// Returns a velocity (Vector2) at a random angle with a specific overall magnitude
private Vector2 GetRandomVelocity(float magnitude) {
Vector2 vector = new Vector2(magnitude, magnitude);
return Util.RotateBy(vector, Random.Range(0, 180));
}
// Cohesion: Steer towards center of mass of flock
private Vector2 Rule1(List<Boid> flock) {
Vector2 center = Vector2.zero;
foreach (Boid boid in flock)
center += boid._position;
center /= _parent.boids.Count;
return (center - this._position) / 100.0f;
}
// Separation: Steer to avoid other Boids within flock
private Vector2 Rule2(List<Boid> flock) {
Vector2 c = Vector2.zero;
foreach (Boid boid in flock) {
Vector2 diff = boid._position - this._position;
if (diff.sqrMagnitude < _parent.boidSeparationRange)
c -= diff;
}
return c;
}
// Alignment: Steer to align with the average heading of the flock
public Vector2 Rule3(List<Boid> flock) {
if (flock.Count == 0)
return Vector2.zero;
Vector2 perceived = Vector2.zero;
foreach (Boid boid in flock)
perceived += boid._velocity;
perceived /= flock.Count;
return (perceived - _velocity) / 8.0f;
}
// Asks Boids to stay within the Boundaries set
private Vector2 RuleBound() {
Vector2 vector = Vector2.zero;
// Boundary X Force
if (_position.x < _parent.Boundary.xMin)
vector.x = _parent.boundaryForce * Mathf.InverseLerp(_parent.Boundary.xMin, _parent.Space.xMin, _position.x);
else if (_position.x > _parent.Boundary.xMax)
vector.x = -_parent.boundaryForce * Mathf.InverseLerp(_parent.Boundary.xMax, _parent.Space.xMax, _position.x);
// Boundary Y Force
if (_position.y < _parent.Boundary.yMin)
vector.y = _parent.boundaryForce * Mathf.InverseLerp(_parent.Boundary.yMin, _parent.Space.yMin, _position.y);
else if (_position.y > _parent.Boundary.yMax)
vector.y = -_parent.boundaryForce * Mathf.InverseLerp(_parent.Boundary.yMax, _parent.Space.yMax, _position.y);
print($"Boundary Vector: {vector}");
return vector;
}
// Returns a list of boids within a certain radius of the Boid, representing it's local 'flock'
private List<Boid> GetFlock(List<Boid> boids, float radius) {
return boids.Where(boid => boid != this && Vector2.Distance(this._position, boid._position) <= radius).ToList();
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 8fa9bbc6d9eb4c368be190feba139e7c
timeCreated: 1589638836

View File

@@ -1,61 +0,0 @@
%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}

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 23e1eaaf69d4ef342ac3ef9590f6c642
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,121 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using Debug = System.Diagnostics.Debug;
using Random = UnityEngine.Random;
public class BoidController : MonoBehaviour {
// Controller Attributes
[NonSerialized] public Rect Space;
[NonSerialized] public Rect Boundary;
// Swarm Attributes
public int boidCount = 50;
public float boidGroupRange = 1.0f;
public float boidStartVelocity = 0.005f;
public float boidVelocityLimit = 1.0f;
public float boidSeparationRange = 2.3f;
// Bias changes how different rules influence individual Boids more or less
[SerializeField] public float separationBias = 0.05f;
[SerializeField] public float alignmentBias = 0.05f;
[SerializeField] public float cohesionBias = 0.05f;
[SerializeField] public float boundaryBias = 1f;
[SerializeField] public float boundaryForce = 10f;
[SerializeField] public bool localFlocks = true;
[SerializeField] public bool edgeWrapping = true;
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);
Gizmos.DrawWireCube(Boundary.center, Boundary.size);
if (focusedBoid != null)
Handles.DrawWireDisc(focusedBoid.transform.position, Vector3.forward, boidGroupRange);
if (Cam == null)
return;
// Draw a Wire Cube for the Cam's Viewport Area
Vector3 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));
}
void Update() {
// Focus a different Boid
if (Input.GetKeyDown("space")) {
// Undo previous Boid's focus
if (focusedBoid != null) {
var oldTriangle = focusedBoid.transform.GetComponent<Triangle>();
oldTriangle.meshRenderer.material.color = new Color32(49, 61, 178, 255);
}
focusedBoid = boids[Random.Range(0, boids.Count)];
var triangle = focusedBoid.transform.GetComponent<Triangle>();
triangle.meshRenderer.material.color = Color.red;
}
}
private void Start() {
// Setup Camera
Cam = Camera.main;
// Size the Rectangle based on the Camera's Orthographic View
float height = 2f * Cam.orthographicSize;
var size = new Vector2(height * Cam.aspect, height);
Space = new Rect((Vector2) transform.position - size / 2, size);
Boundary = new Rect(Vector2.zero, Space.size * 0.95f);
Boundary.center = Space.center;
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
boid.transform.parent = transform;
boids.Add(boid.GetComponent<Boid>());
}
}
public void RemoveBoids(int n) {
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(-Boundary.size.x, Boundary.size.x) / 2,
Random.Range(-Boundary.size.y, Boundary.size.y) / 2);
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7d72224fef7a4fb4a998b0980fe0eb77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,57 +0,0 @@
%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}

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 79543cb69dabd5846a1789cccbdeefd8
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,324 +0,0 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!181963792 &2655988077585873504
Preset:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: BoidController
m_TargetType:
m_NativeTypeID: 114
m_ManagedTypePPtr: {fileID: 11500000, guid: 7d72224fef7a4fb4a998b0980fe0eb77,
type: 3}
m_ManagedTypeFallback:
m_Properties:
- target: {fileID: 0}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_EditorHideFlags
value: 0
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: m_EditorClassIdentifier
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boidCount
value: 62
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boidGroupRange
value: 3.68
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boidStartVelocity
value: 0.05
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boidVelocityLimit
value: 0.3
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: separationRange
value: 2.82
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: separationBias
value: 0.01
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: alignmentBias
value: 0.05
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: cohesionBias
value: 0.05
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: localFlocks
value: 1
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boidObject
value:
objectReference: {fileID: 1737515784064720040, guid: 23e1eaaf69d4ef342ac3ef9590f6c642,
type: 3}
- target: {fileID: 0}
propertyPath: boids.Array.size
value: 62
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[0]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[1]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[2]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[3]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[4]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[5]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[6]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[7]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[8]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[9]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[10]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[11]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[12]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[13]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[14]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[15]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[16]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[17]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[18]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[19]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[20]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[21]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[22]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[23]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[24]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[25]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[26]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[27]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[28]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[29]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[30]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[31]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[32]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[33]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[34]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[35]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[36]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[37]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[38]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[39]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[40]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[41]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[42]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[43]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[44]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[45]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[46]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[47]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[48]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[49]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[50]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[51]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[52]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[53]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[54]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[55]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[56]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[57]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[58]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[59]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[60]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: boids.Array.data[61]
value:
objectReference: {fileID: 0}
- target: {fileID: 0}
propertyPath: cam
value:
objectReference: {fileID: 0}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6a61920c5c2f5524dbc2bffcf29fcbc5
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2655988077585873504
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,38 +0,0 @@
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);
// Check must be performed or Boids will be added outside of Gameplay
if (EditorGUI.EndChangeCheck() && Application.isPlaying) {
int diff = controller.boidCount - controller.boids.Count;
if (diff > 1)
controller.AddBoids(diff);
else if (diff < 0)
controller.RemoveBoids(Mathf.Abs(diff));
}
// Basic Boid Controller Attributes
controller.boidGroupRange = EditorGUILayout.Slider("Group Range", controller.boidGroupRange, 0.01f, 10.0f);
controller.boidStartVelocity = EditorGUILayout.Slider("Start Velocity", controller.boidStartVelocity, 0.01f, 5.0f);
controller.boidVelocityLimit = EditorGUILayout.Slider("Max Velocity", controller.boidVelocityLimit, 0.01f, 7.5f);
controller.boidSeparationRange = EditorGUILayout.Slider("Separation Range", controller.boidSeparationRange, 0.01f, 5.0f);
controller.boundaryForce = EditorGUILayout.Slider("Boundary Force", controller.boundaryForce, 0.5f, 5.0f);
// Boid Bias Attributes
controller.alignmentBias = EditorGUILayout.Slider("Alignment Bias", controller.alignmentBias, 0.001f, 0.75f);
controller.cohesionBias = EditorGUILayout.Slider("Cohesion Bias", controller.cohesionBias, 0.001f, 0.75f);
controller.separationBias = EditorGUILayout.Slider("Separation Bias", controller.separationBias, 0.001f, 0.75f);
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);
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6ec8daef16a2459989f9d8b81bb248ea
timeCreated: 1589767516

View File

@@ -1,37 +0,0 @@
 using UnityEditor;
using UnityEngine;
/// <summary>
/// Prevents script compilation and reload while in play mode.
/// The editor will show a the spinning reload icon if there are unapplied changes but will not actually
/// apply them until playmode is exited.
/// Note: Script compile errors will not be shown while in play mode.
/// Derived from the instructions here:
/// https://support.unity3d.com/hc/en-us/articles/210452343-How-to-stop-automatic-assembly-compilation-from-script
/// </summary>
[InitializeOnLoad]
public class DisableScriptReload
{
static DisableScriptReload()
{
EditorApplication.playModeStateChanged
+= OnPlayModeStateChanged;
}
static void OnPlayModeStateChanged(PlayModeStateChange stateChange)
{
switch (stateChange) {
case (PlayModeStateChange.EnteredPlayMode): {
EditorApplication.LockReloadAssemblies();
Debug.Log ("Assembly Reload locked as entering play mode");
break;
}
case (PlayModeStateChange.ExitingPlayMode): {
Debug.Log ("Assembly Reload unlocked as exiting play mode");
EditorApplication.UnlockReloadAssemblies();
break;
}
}
}
}

View File

@@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 6a46ee76c3b4473f9aff1b62cf8674dc
timeCreated: 1589846269

View File

@@ -233,17 +233,27 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
boidCount: 153
boidGroupRange: 3.6
boidGroupRange: 2.69
boidStartVelocity: 0.05
boidVelocityLimit: 0.3
separationRange: 2.8
separationBias: 0.01
alignmentBias: 0.05
globalBias: 1
separationBias: 0.014
alignmentBias: 0.194
cohesionBias: 0.05
boundaryBias: 0.063
enableSeparation: 1
enableAlignment: 1
enableCohesion: 1
enableBoundary: 1
boidSeparationRange: 5
boundaryForce: 0.352
localFlocks: 1
edgeWrapping: 1
circleVertexCount: 360
circleWidth: 0.1
focusedBoid: {fileID: 0}
boidObject: {fileID: 1737515784064720040, guid: 23e1eaaf69d4ef342ac3ef9590f6c642,
type: 3}
cam: {fileID: 519420031}
--- !u!4 &1321165554
Transform:
m_ObjectHideFlags: 0

View File

@@ -1,43 +0,0 @@
using System;
using System.Linq;
using UnityEngine;
public class Triangle : MonoBehaviour {
[NonSerialized] public Color FillColor = Color.red;
public MeshRenderer meshRenderer;
private void Start () {
// Create Vector2 vertices
var vertices2D = new Vector2[] {
new Vector2(0,1),
new Vector2(0.4f,0),
new Vector2(-0.4f,0),
};
var vertices3D = System.Array.ConvertAll<Vector2, Vector3>(vertices2D, v => v);
// Use the triangulator to get indices for creating triangles
var triangulator = new Triangulator(vertices2D);
var indices = triangulator.Triangulate();
// Generate a color for each vertex
var colors = Enumerable.Repeat(FillColor, vertices3D.Length).ToArray();
// Create the mesh
var mesh = new Mesh {
vertices = vertices3D,
triangles = indices,
colors = colors
};
mesh.RecalculateNormals();
mesh.RecalculateBounds();
// Set up game object with mesh;
meshRenderer = gameObject.AddComponent<MeshRenderer>();
meshRenderer.material = (Material) Resources.Load("BoidMaterial");
var filter = gameObject.AddComponent<MeshFilter>();
filter.mesh = mesh;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 39c543193832a9745a8985fb0e672377
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,126 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// This script can be used to split a 2D polygon into triangles.
/// The algorithm supports concave polygons, but not polygons with holes,
/// or multiple polygons at once.
/// Taken from <see cref="http://wiki.unity3d.com/index.php?title=Triangulator"/>
/// </summary>
public class Triangulator
{
private readonly List<Vector2> _mPoints;
public Triangulator(IEnumerable<Vector2> points)
{
_mPoints = new List<Vector2>(points);
}
public int[] Triangulate()
{
var indices = new List<int>();
var n = _mPoints.Count;
if (n < 3)
return indices.ToArray();
var V = new int[n];
if (Area() > 0) {
for (var v = 0; v < n; v++)
V[v] = v;
} else {
for (var v = 0; v < n; v++)
V[v] = n - 1 - v;
}
var nv = n;
var count = 2 * nv;
for (int m = 0, v = nv - 1; nv > 2;) {
if (count-- <= 0)
return indices.ToArray();
var u = v;
if (nv <= u)
u = 0;
v = u + 1;
if (nv <= v)
v = 0;
var w = v + 1;
if (nv <= w)
w = 0;
if (Snip(u, v, w, nv, V)) {
int a, b, c, s, t;
a = V[u];
b = V[v];
c = V[w];
indices.Add(a);
indices.Add(b);
indices.Add(c);
m++;
for (s = v, t = v + 1; t < nv; s++, t++)
V[s] = V[t];
nv--;
count = 2 * nv;
}
}
indices.Reverse();
return indices.ToArray();
}
private float Area()
{
var n = _mPoints.Count;
var A = 0.0f;
for (int p = n - 1, q = 0; q < n; p = q++) {
var pval = _mPoints[p];
var qval = _mPoints[q];
A += pval.x * qval.y - qval.x * pval.y;
}
return A * 0.5f;
}
private bool Snip(int u, int v, int w, int n, int[] V)
{
int p;
var A = _mPoints[V[u]];
var B = _mPoints[V[v]];
var C = _mPoints[V[w]];
if (Mathf.Epsilon > (B.x - A.x) * (C.y - A.y) - (B.y - A.y) * (C.x - A.x))
return false;
for (p = 0; p < n; p++) {
if (p == u || p == v || p == w)
continue;
var P = _mPoints[V[p]];
if (InsideTriangle(A, B, C, P))
return false;
}
return true;
}
private static bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
{
float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
float cCROSSap, bCROSScp, aCROSSbp;
ax = C.x - B.x;
ay = C.y - B.y;
bx = A.x - C.x;
by = A.y - C.y;
cx = B.x - A.x;
cy = B.y - A.y;
apx = P.x - A.x;
apy = P.y - A.y;
bpx = P.x - B.x;
bpy = P.y - B.y;
cpx = P.x - C.x;
cpy = P.y - C.y;
aCROSSbp = ax * bpy - ay * bpx;
cCROSSap = cx * apy - cy * apx;
bCROSScp = bx * cpy - by * cpx;
return aCROSSbp >= 0.0f && bCROSScp >= 0.0f && cCROSSap >= 0.0f;
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 959398144280d9145b8e5c4ec9f36837
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,43 +0,0 @@
using UnityEditor;
using UnityEngine;
public class Util {
public static Vector2 RotateBy(Vector2 v, float a) {
var ca = Mathf.Cos(a);
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));
}
public static Vector2 LimitVelocity(Vector2 v, float max) {
if (v.magnitude > max) {
v = (v / v.magnitude) * max;
}
return v;
}
public static Vector2 AbsVector(Vector2 vector) {
return new Vector2(vector.x, vector.y);
}
public class ReadOnlyAttribute : PropertyAttribute {
}
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
public class ReadOnlyDrawer : PropertyDrawer {
public override float GetPropertyHeight(SerializedProperty property,
GUIContent label) {
return EditorGUI.GetPropertyHeight(property, label, true);
}
public override void OnGUI(Rect position,
SerializedProperty property,
GUIContent label) {
GUI.enabled = false;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9a91db8d912fd1d4dbebfaf69dad59e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -31,6 +31,9 @@ GraphicsSettings:
m_AlwaysIncludedShaders:
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}

View File

@@ -12,7 +12,7 @@ PlayerSettings:
targetDevice: 2
useOnDemandResources: 0
accelerometerFrequency: 60
companyName: DefaultCompany
companyName: Xevion
productName: Boids
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}

View File

@@ -4,7 +4,7 @@
UnityConnectSettings:
m_ObjectHideFlags: 0
serializedVersion: 1
m_Enabled: 0
m_Enabled: 1
m_TestMode: 0
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events