mirror of
https://github.com/Xevion/Boids.git
synced 2025-12-06 05:14:27 -06:00
Moved all scripts into Scripts folder, project organization, more comments, other stuff (?)
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fa9bbc6d9eb4c368be190feba139e7c
|
||||
timeCreated: 1589638836
|
||||
@@ -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}
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23e1eaaf69d4ef342ac3ef9590f6c642
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7d72224fef7a4fb4a998b0980fe0eb77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}
|
||||
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79543cb69dabd5846a1789cccbdeefd8
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a61920c5c2f5524dbc2bffcf29fcbc5
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2655988077585873504
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ec8daef16a2459989f9d8b81bb248ea
|
||||
timeCreated: 1589767516
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a46ee76c3b4473f9aff1b62cf8674dc
|
||||
timeCreated: 1589846269
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39c543193832a9745a8985fb0e672377
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 959398144280d9145b8e5c4ec9f36837
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a91db8d912fd1d4dbebfaf69dad59e3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user