From aaec1923eb0fc40e21d042f91672977f775bb1a6 Mon Sep 17 00:00:00 2001 From: Xevion Date: Sat, 16 May 2020 22:01:15 -0500 Subject: [PATCH] More cleanup making code cleaner, made Rectangle Boundaries automatically size to camera's view, automatic random boid placement, value tweaking --- Assets/Boid.cs | 11 +- Assets/BoidController.cs | 33 ++--- Assets/Resources/BoidMaterial.mat | 6 +- Assets/Scenes/SampleScene.unity | 198 +++++++++++++++++++++++++-- Assets/Util.cs | 11 ++ Assets/Util.cs.meta | 11 ++ ProjectSettings/EditorSettings.asset | 8 +- 7 files changed, 236 insertions(+), 42 deletions(-) create mode 100644 Assets/Util.cs create mode 100644 Assets/Util.cs.meta diff --git a/Assets/Boid.cs b/Assets/Boid.cs index 85d3f85..e8986ed 100644 --- a/Assets/Boid.cs +++ b/Assets/Boid.cs @@ -1,14 +1,13 @@ using System; using System.Collections.Generic; using UnityEngine; -using UnityEngine.Analytics; using Random = UnityEngine.Random; // Boids are represented by a moving, rotating triangle. // Boids should communicate with sibling Boids public class Boid : MonoBehaviour { [NonSerialized] public Vector2 position = Vector2.zero; - public Vector2 velocity; + [NonSerialized] public Vector2 velocity; [NonSerialized] public bool IsWrappingX = false; [NonSerialized] public bool IsWrappingY = false; private BoidController parent; @@ -23,12 +22,12 @@ public class Boid : MonoBehaviour { // Updates the rotation of the object based on the Velocity transform.rotation = Quaternion.Euler(0, 0, Mathf.Rad2Deg * -Mathf.Atan2(velocity.x, velocity.y)); } - + public Vector2 NextPosition(List boids, float[] magnitudes) { // Skip Flock Calculations if wrapping in progress if (IsWrappingX || IsWrappingY) return position + velocity; - + // Acquires all Boids within the local flock List flock = GetFlock(parent.boids, parent.boidGroupRange); @@ -58,7 +57,7 @@ public class Boid : MonoBehaviour { Vector2 center = Vector2.zero; foreach (Boid boid in flock) center += boid.position; - center /= flock.Count; + center /= parent.boids.Count; return (center - this.position) / 100; } @@ -67,7 +66,7 @@ public class Boid : MonoBehaviour { Vector2 c = Vector2.zero; foreach (Boid boid in flock) { Vector2 diff = boid.position - this.position; - if (diff.magnitude < 5) + if (diff.magnitude < parent.separationRange) c -= diff; } diff --git a/Assets/BoidController.cs b/Assets/BoidController.cs index 6b823aa..2221fd1 100644 --- a/Assets/BoidController.cs +++ b/Assets/BoidController.cs @@ -1,28 +1,30 @@ using System; using System.Collections.Generic; using UnityEngine; -using Debug = System.Diagnostics.Debug; using Random = UnityEngine.Random; public class BoidController : MonoBehaviour { // Controller Attributes - public Rect space; + [NonSerialized] public Rect space; // Swarm Attributes public int boidCount = 50; public float boidGroupRange = 1.0f; public float boidStartVelocity = 0.005f; - public float boidVelocityLimit = 2.0f; + public float boidVelocityLimit = 1.0f; + public float separationRange = 2.3f; // 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; + public float separationBias = 0.05f; + public float alignmentBias = 0.05f; + public float cohesionBias = 0.05f; // Boid Object Prefab public GameObject boidObject; + // Boid Objects for Updates public List boids = new List(); + // Used for wrapping Camera _cam; @@ -34,15 +36,16 @@ public class BoidController : MonoBehaviour { // Setup Camera _cam = Camera.main; - var size = new Vector2(142, 80); - space = new Rect((Vector2) transform.position - (size / 2), size); - - // Size the Rectangle - _cam.rect = space; + // Size the Rectangle based on the Camera's Orthographic View + float height = 2f * _cam.orthographicSize; + float width = height * _cam.aspect; + space = new Rect(transform.position, new Vector2(width, height)); // Add in Boid Objects / Spawn Boid Prefabs for (int i = 0; i < boidCount; i++) { - var position = new Vector2(Random.Range(-15, 15), Random.Range(-15, 15)); + 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); GameObject boid = Instantiate(boidObject, position, Quaternion.identity); boid.transform.parent = transform; @@ -54,13 +57,11 @@ public class BoidController : MonoBehaviour { private void Update() { // Wrapping Functionality foreach (Boid boid in boids) { - print($"{boid.IsWrappingX} {boid.IsWrappingY}"); - if (!space.Contains(boid.position)) { // Activate Wrap, Move Vector2 newPosition = boid.transform.position; Vector3 viewportPosition = _cam.WorldToViewportPoint(newPosition); - + if (!boid.IsWrappingX && (viewportPosition.x > 1 || viewportPosition.x < 0)) { newPosition.x = -newPosition.x; boid.IsWrappingX = true; @@ -85,7 +86,7 @@ public class BoidController : MonoBehaviour { // Update all Boid positions foreach (Boid boid in boids) { Vector2 next = boid.NextPosition(boids, magnitudes); - + boid.position = next; boid.transform.position = new Vector3(next.x, next.y, 0); } diff --git a/Assets/Resources/BoidMaterial.mat b/Assets/Resources/BoidMaterial.mat index 076241a..302ad1b 100644 --- a/Assets/Resources/BoidMaterial.mat +++ b/Assets/Resources/BoidMaterial.mat @@ -7,7 +7,7 @@ Material: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: New Material + m_Name: BoidMaterial m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} m_ShaderKeywords: m_LightmapFlags: 4 @@ -61,7 +61,7 @@ Material: - _DetailNormalMapScale: 1 - _DstBlend: 0 - _GlossMapScale: 1 - - _Glossiness: 0.5 + - _Glossiness: 0 - _GlossyReflections: 1 - _Metallic: 0 - _Mode: 0 @@ -73,5 +73,5 @@ Material: - _UVSec: 0 - _ZWrite: 1 m_Colors: - - _Color: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 0.16135636, g: 0.2708125, b: 0.6981132, a: 1} - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity index e5ecd0a..ae5f67a 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/SampleScene.unity @@ -50,12 +50,11 @@ LightmapSettings: m_BounceScale: 1 m_IndirectOutputScale: 1 m_AlbedoBoost: 1 - m_TemporalCoherenceThreshold: 1 m_EnvironmentLightingMode: 0 m_EnableBakedLightmaps: 0 m_EnableRealtimeLightmaps: 0 m_LightmapEditorSettings: - serializedVersion: 10 + serializedVersion: 12 m_Resolution: 2 m_BakeResolution: 40 m_AtlasSize: 1024 @@ -63,6 +62,7 @@ LightmapSettings: m_AOMaxDistance: 1 m_CompAOExponent: 1 m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 m_Padding: 2 m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 @@ -77,10 +77,16 @@ LightmapSettings: m_PVRDirectSampleCount: 32 m_PVRSampleCount: 500 m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 m_PVRFilterTypeDirect: 0 m_PVRFilterTypeIndirect: 0 m_PVRFilterTypeAO: 0 - m_PVRFilteringMode: 1 + m_PVREnvironmentMIS: 0 m_PVRCulling: 1 m_PVRFilteringGaussRadiusDirect: 1 m_PVRFilteringGaussRadiusIndirect: 5 @@ -89,6 +95,7 @@ LightmapSettings: m_PVRFilteringAtrousPositionSigmaIndirect: 2 m_PVRFilteringAtrousPositionSigmaAO: 1 m_ShowResolutionOverlay: 1 + m_ExportTrainingData: 0 m_LightingDataAsset: {fileID: 0} m_UseShadowmask: 1 --- !u!196 &4 @@ -116,9 +123,10 @@ NavMeshSettings: --- !u!1 &519420028 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 5 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - component: {fileID: 519420032} - component: {fileID: 519420031} @@ -133,20 +141,28 @@ GameObject: --- !u!81 &519420029 AudioListener: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_Enabled: 1 --- !u!20 &519420031 Camera: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_Enabled: 1 serializedVersion: 2 m_ClearFlags: 2 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_BackGroundColor: {r: 0.13207549, g: 0.13207549, b: 0.13207549, a: 1} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -157,7 +173,7 @@ Camera: far clip plane: 1000 field of view: 60 orthographic: 1 - orthographic size: 5 + orthographic size: 40 m_Depth: -1 m_CullingMask: serializedVersion: 2 @@ -176,13 +192,165 @@ Camera: --- !u!4 &519420032 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalPosition: {x: 0, y: 0, z: -15} 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!1 &1321165552 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1321165554} + - component: {fileID: 1321165553} + m_Layer: 0 + m_Name: BoidController + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1321165553 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321165552} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7d72224fef7a4fb4a998b0980fe0eb77, type: 3} + m_Name: + m_EditorClassIdentifier: + space: + serializedVersion: 2 + x: 0 + y: 0 + width: 35 + height: 20 + boidCount: 150 + boidGroupRange: 5 + boidStartVelocity: 0.05 + boidVelocityLimit: 0.8 + separationRange: 2.3 + separationBias: 0.01 + alignmentBias: 0.04 + cohesionBias: 0.009 + boidObject: {fileID: 1737515784064720040, guid: 23e1eaaf69d4ef342ac3ef9590f6c642, + type: 3} + boids: [] +--- !u!4 &1321165554 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1321165552} + 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: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &2143969959 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2143969961} + - component: {fileID: 2143969960} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &2143969960 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2143969959} + m_Enabled: 1 + serializedVersion: 9 + m_Type: 1 + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 0 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &2143969961 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2143969959} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/Util.cs b/Assets/Util.cs new file mode 100644 index 0000000..312a991 --- /dev/null +++ b/Assets/Util.cs @@ -0,0 +1,11 @@ +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)); + } +} \ No newline at end of file diff --git a/Assets/Util.cs.meta b/Assets/Util.cs.meta new file mode 100644 index 0000000..f2b1332 --- /dev/null +++ b/Assets/Util.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a91db8d912fd1d4dbebfaf69dad59e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset index 8d9e83b..81e78ca 100644 --- a/ProjectSettings/EditorSettings.asset +++ b/ProjectSettings/EditorSettings.asset @@ -8,14 +8,18 @@ EditorSettings: m_SerializationMode: 2 m_LineEndingsForNewScripts: 2 m_DefaultBehaviorMode: 1 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} m_SpritePackerMode: 4 m_SpritePackerPaddingPower: 1 m_EtcTextureCompressorBehavior: 1 m_EtcTextureFastCompressor: 1 m_EtcTextureNormalCompressor: 2 m_EtcTextureBestCompressor: 4 - m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef m_ProjectGenerationRootNamespace: - m_UserGeneratedProjectSuffix: m_CollabEditorSettings: inProgressEnabled: 1 + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_AsyncShaderCompilation: 1