From cdcb4f1781e9b7ff7dfe82279e0986c88043a06b Mon Sep 17 00:00:00 2001 From: "Alex.Kirel" Date: Wed, 26 Jul 2023 16:38:51 +0500 Subject: [PATCH] Added Trail Effect library. --- Assets/TrailEffect/Effects.meta | 5 + Assets/TrailEffect/Effects/Trails.meta | 5 + Assets/TrailEffect/Effects/Trails/Editor.meta | 5 + .../Trails/Editor/PCTKEffectsIntroDialogue.cs | 28 + .../Editor/PCTKEffectsIntroDialogue.cs.meta | 8 + .../Effects/Trails/Editor/SmokePlumeEditor.cs | 19 + .../Trails/Editor/SmokePlumeEditor.cs.meta | 8 + .../Effects/Trails/Editor/SmokeTrailEditor.cs | 18 + .../Trails/Editor/SmokeTrailEditor.cs.meta | 8 + .../Effects/Trails/Editor/TrailEditor.cs | 17 + .../Effects/Trails/Editor/TrailEditor.cs.meta | 8 + .../Effects/Trails/Editor/TrailEditor_Base.cs | 113 ++++ .../Trails/Editor/TrailEditor_Base.cs.meta | 8 + .../Trails/Editor/TrailPreviewUtillity.cs | 275 ++++++++++ .../Editor/TrailPreviewUtillity.cs.meta | 8 + Assets/TrailEffect/Effects/Trails/Icons.meta | 5 + .../Effects/Trails/Icons/SmokPlumeIcon.png | Bin 0 -> 5129 bytes .../Effects/Trails/Icons/SmokeTrailIcon.png | Bin 0 -> 5256 bytes .../Effects/Trails/Icons/TrailIcon.png | Bin 0 -> 4872 bytes Assets/TrailEffect/Effects/Trails/PCTrail.cs | 60 ++ .../Effects/Trails/PCTrail.cs.meta | 12 + .../Effects/Trails/PCTrailPoint.cs | 43 ++ .../Effects/Trails/PCTrailPoint.cs.meta | 12 + .../Effects/Trails/PCTrailRendererData.cs | 41 ++ .../Trails/PCTrailRendererData.cs.meta | 12 + .../TrailEffect/Effects/Trails/Resources.meta | 5 + .../Effects/Trails/Resources/PCTK.meta | 5 + .../Trails/Resources/PCTK/Effects.meta | 5 + .../Trails/Resources/PCTK/Effects/Trails.meta | 5 + .../TrailEffect/Effects/Trails/SmokePlume.cs | 88 +++ .../Effects/Trails/SmokePlume.cs.meta | 12 + .../TrailEffect/Effects/Trails/SmokeTrail.cs | 70 +++ .../Effects/Trails/SmokeTrail.cs.meta | 12 + .../Effects/Trails/SmokeTrailPoint.cs | 16 + .../Effects/Trails/SmokeTrailPoint.cs.meta | 12 + .../TrailEffect/Effects/Trails/SmoothTrail.cs | 188 +++++++ .../Effects/Trails/SmoothTrail.cs.meta | 12 + Assets/TrailEffect/Effects/Trails/Trail.cs | 61 +++ .../TrailEffect/Effects/Trails/Trail.cs.meta | 12 + .../Effects/Trails/TrailRenderer_Base.cs | 512 ++++++++++++++++++ .../Effects/Trails/TrailRenderer_Base.cs.meta | 12 + Assets/TrailEffect/Generic.meta | 5 + Assets/TrailEffect/Generic/Editor.meta | 5 + .../Generic/Editor/IntroDialogue.cs | 81 +++ .../Generic/Editor/IntroDialogue.cs.meta | 8 + Assets/TrailEffect/Generic/Resources.meta | 5 + .../TrailEffect/Generic/Resources/PCTK.meta | 5 + .../Generic/Resources/PCTK/Generic.meta | 5 + .../TrailEffect/Generic/VersionInformation.cs | 44 ++ .../Generic/VersionInformation.cs.meta | 8 + Assets/TrailEffect/Materials.meta | 9 + Assets/TrailEffect/Materials/Arrow.mat | 40 ++ Assets/TrailEffect/Materials/Arrow.mat.meta | 4 + Assets/TrailEffect/Materials/BarrelSmoke.mat | 52 ++ .../Materials/BarrelSmoke.mat.meta | 4 + .../TrailEffect/Materials/FlameSwordTrail.mat | 52 ++ .../Materials/FlameSwordTrail.mat.meta | 4 + .../LowPolyTankTextureTreadDecal.mat | 34 ++ .../LowPolyTankTextureTreadDecal.mat.meta | 4 + Assets/TrailEffect/Materials/MuzzleFlash.mat | 52 ++ .../Materials/MuzzleFlash.mat.meta | 4 + .../TrailEffect/Materials/SelectionTrail.mat | 37 ++ .../Materials/SelectionTrail.mat.meta | 4 + .../TrailEffect/Materials/SwordSwingMat.mat | 40 ++ .../Materials/SwordSwingMat.mat.meta | 4 + .../Materials/SwordSwingRoughMat.mat | 34 ++ .../Materials/SwordSwingRoughMat.mat.meta | 4 + .../TrailEffect/Materials/TankShellTrail.mat | 37 ++ .../Materials/TankShellTrail.mat.meta | 4 + Assets/TrailEffect/Materials/TankSmoke.mat | 52 ++ .../TrailEffect/Materials/TankSmoke.mat.meta | 4 + Assets/TrailEffect/Materials/UsedShell.mat | 28 + .../TrailEffect/Materials/UsedShell.mat.meta | 4 + Assets/TrailEffect/Textures.meta | 9 + Assets/TrailEffect/Textures/Arrow 1.png | Bin 0 -> 3685 bytes Assets/TrailEffect/Textures/Arrow.png | Bin 0 -> 3670 bytes Assets/TrailEffect/Textures/SmokePlume 2.png | Bin 0 -> 4266 bytes Assets/TrailEffect/Textures/SmokePlume.png | Bin 0 -> 18401 bytes Assets/TrailEffect/Textures/swingFX.png | Bin 0 -> 8559 bytes Assets/TrailEffect/Textures/swingFXRough.png | Bin 0 -> 22769 bytes Assets/TrailEffect/Utillities.meta | 5 + .../TrailEffect/Utillities/CircularBuffer.cs | 286 ++++++++++ .../Utillities/CircularBuffer.cs.meta | 8 + Assets/TrailEffect/Utillities/Editor.meta | 5 + .../Utillities/Editor/RangePropertyDrawer.cs | 34 ++ .../Editor/RangePropertyDrawer.cs.meta | 8 + Assets/TrailEffect/Utillities/GizmosExtra.cs | 33 ++ .../Utillities/GizmosExtra.cs.meta | 8 + Assets/TrailEffect/Utillities/Range.cs | 15 + Assets/TrailEffect/Utillities/Range.cs.meta | 8 + fie.csproj | 21 + 91 files changed, 2862 insertions(+) create mode 100644 Assets/TrailEffect/Effects.meta create mode 100644 Assets/TrailEffect/Effects/Trails.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Icons.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Icons/SmokPlumeIcon.png create mode 100644 Assets/TrailEffect/Effects/Trails/Icons/SmokeTrailIcon.png create mode 100644 Assets/TrailEffect/Effects/Trails/Icons/TrailIcon.png create mode 100644 Assets/TrailEffect/Effects/Trails/PCTrail.cs create mode 100644 Assets/TrailEffect/Effects/Trails/PCTrail.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs create mode 100644 Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs create mode 100644 Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Resources.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Resources/PCTK.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects/Trails.meta create mode 100644 Assets/TrailEffect/Effects/Trails/SmokePlume.cs create mode 100644 Assets/TrailEffect/Effects/Trails/SmokePlume.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/SmokeTrail.cs create mode 100644 Assets/TrailEffect/Effects/Trails/SmokeTrail.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs create mode 100644 Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/SmoothTrail.cs create mode 100644 Assets/TrailEffect/Effects/Trails/SmoothTrail.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/Trail.cs create mode 100644 Assets/TrailEffect/Effects/Trails/Trail.cs.meta create mode 100644 Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs create mode 100644 Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs.meta create mode 100644 Assets/TrailEffect/Generic.meta create mode 100644 Assets/TrailEffect/Generic/Editor.meta create mode 100644 Assets/TrailEffect/Generic/Editor/IntroDialogue.cs create mode 100644 Assets/TrailEffect/Generic/Editor/IntroDialogue.cs.meta create mode 100644 Assets/TrailEffect/Generic/Resources.meta create mode 100644 Assets/TrailEffect/Generic/Resources/PCTK.meta create mode 100644 Assets/TrailEffect/Generic/Resources/PCTK/Generic.meta create mode 100644 Assets/TrailEffect/Generic/VersionInformation.cs create mode 100644 Assets/TrailEffect/Generic/VersionInformation.cs.meta create mode 100644 Assets/TrailEffect/Materials.meta create mode 100644 Assets/TrailEffect/Materials/Arrow.mat create mode 100644 Assets/TrailEffect/Materials/Arrow.mat.meta create mode 100644 Assets/TrailEffect/Materials/BarrelSmoke.mat create mode 100644 Assets/TrailEffect/Materials/BarrelSmoke.mat.meta create mode 100644 Assets/TrailEffect/Materials/FlameSwordTrail.mat create mode 100644 Assets/TrailEffect/Materials/FlameSwordTrail.mat.meta create mode 100644 Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat create mode 100644 Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat.meta create mode 100644 Assets/TrailEffect/Materials/MuzzleFlash.mat create mode 100644 Assets/TrailEffect/Materials/MuzzleFlash.mat.meta create mode 100644 Assets/TrailEffect/Materials/SelectionTrail.mat create mode 100644 Assets/TrailEffect/Materials/SelectionTrail.mat.meta create mode 100644 Assets/TrailEffect/Materials/SwordSwingMat.mat create mode 100644 Assets/TrailEffect/Materials/SwordSwingMat.mat.meta create mode 100644 Assets/TrailEffect/Materials/SwordSwingRoughMat.mat create mode 100644 Assets/TrailEffect/Materials/SwordSwingRoughMat.mat.meta create mode 100644 Assets/TrailEffect/Materials/TankShellTrail.mat create mode 100644 Assets/TrailEffect/Materials/TankShellTrail.mat.meta create mode 100644 Assets/TrailEffect/Materials/TankSmoke.mat create mode 100644 Assets/TrailEffect/Materials/TankSmoke.mat.meta create mode 100644 Assets/TrailEffect/Materials/UsedShell.mat create mode 100644 Assets/TrailEffect/Materials/UsedShell.mat.meta create mode 100644 Assets/TrailEffect/Textures.meta create mode 100644 Assets/TrailEffect/Textures/Arrow 1.png create mode 100644 Assets/TrailEffect/Textures/Arrow.png create mode 100644 Assets/TrailEffect/Textures/SmokePlume 2.png create mode 100644 Assets/TrailEffect/Textures/SmokePlume.png create mode 100644 Assets/TrailEffect/Textures/swingFX.png create mode 100644 Assets/TrailEffect/Textures/swingFXRough.png create mode 100644 Assets/TrailEffect/Utillities.meta create mode 100644 Assets/TrailEffect/Utillities/CircularBuffer.cs create mode 100644 Assets/TrailEffect/Utillities/CircularBuffer.cs.meta create mode 100644 Assets/TrailEffect/Utillities/Editor.meta create mode 100644 Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs create mode 100644 Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs.meta create mode 100644 Assets/TrailEffect/Utillities/GizmosExtra.cs create mode 100644 Assets/TrailEffect/Utillities/GizmosExtra.cs.meta create mode 100644 Assets/TrailEffect/Utillities/Range.cs create mode 100644 Assets/TrailEffect/Utillities/Range.cs.meta diff --git a/Assets/TrailEffect/Effects.meta b/Assets/TrailEffect/Effects.meta new file mode 100644 index 0000000..282db63 --- /dev/null +++ b/Assets/TrailEffect/Effects.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 6a726ba0fdae4d440984f5fdb4733d17 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails.meta b/Assets/TrailEffect/Effects/Trails.meta new file mode 100644 index 0000000..b5b2a9f --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f8269202cdc317242afb02d19b41b357 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor.meta b/Assets/TrailEffect/Effects/Trails/Editor.meta new file mode 100644 index 0000000..fde7a7e --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 35bda278aee224f419e59e01d4a4ff06 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs b/Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs new file mode 100644 index 0000000..08c9424 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs @@ -0,0 +1,28 @@ +using UnityEditor; +using UnityEngine; +using System.Collections; +using PigeonCoopToolkit.Generic.Editor; + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + [InitializeOnLoad] + public class PCTKEffectsIntroDialogue + { + static PCTKEffectsIntroDialogue() + { + EditorApplication.update+=Update; + } + + static void Update() + { + if (EditorPrefs.GetBool("PCTK/Effects/Trails/ShownIntroDialogue") == false) + { + IntroDialogue dialogue = EditorWindow.GetWindow(true, "Thanks for your purchase!"); + dialogue.Init(Resources.Load("PCTK/Effects/Trails/banner") as Texture2D, new Generic.VersionInformation("Better Trails", 1, 3, 0), Application.dataPath + "/PigeonCoopToolkit/__Effects (Trails) Examples/Pigeon Coop Toolkit - Effects (Trails).pdf"); + EditorPrefs.SetBool("PCTK/Effects/Trails/ShownIntroDialogue",true); + } + } + } + +} + \ No newline at end of file diff --git a/Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs.meta b/Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs.meta new file mode 100644 index 0000000..f479bd4 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/PCTKEffectsIntroDialogue.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 83aee9145022a53418a0c515cc492327 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs b/Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs new file mode 100644 index 0000000..52e52ee --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + [CustomEditor(typeof(SmokePlume))] + [CanEditMultipleObjects] + public class SmokePlumeEditor : TrailEditor_Base + { + protected override void DrawTrailSpecificGUI() + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("ConstantForce")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("RandomForceScale")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("TimeBetweenPoints")); + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs.meta b/Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs.meta new file mode 100644 index 0000000..7c4cee3 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/SmokePlumeEditor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ddcb2ed96cba10e4da2cae8ff8533fda +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs b/Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs new file mode 100644 index 0000000..574ba8a --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + [CustomEditor(typeof(SmokeTrail))] + [CanEditMultipleObjects] + public class SmokeTrailEditor : TrailEditor_Base + { + protected override void DrawTrailSpecificGUI() + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("RandomForceScale")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("MinVertexDistance")); + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs.meta b/Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs.meta new file mode 100644 index 0000000..a823df9 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/SmokeTrailEditor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bf32d2b00d1c88c4b91cf689b5f770c5 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs new file mode 100644 index 0000000..713b128 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + [CustomEditor(typeof(Trail))] + [CanEditMultipleObjects] + public class TrailEditor : TrailEditor_Base + { + protected override void DrawTrailSpecificGUI() + { + EditorGUILayout.PropertyField(serializedObject.FindProperty("MinVertexDistance")); + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs.meta b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs.meta new file mode 100644 index 0000000..8cde7a7 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dba587684cc69dc4097b307d0bacf81d +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs new file mode 100644 index 0000000..29f4673 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs @@ -0,0 +1,113 @@ +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; + + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + + public class TrailEditor_Base : UnityEditor.Editor + { + + + public static TrailPreviewUtillity win; + + public override void OnInspectorGUI() + { + + TrailRenderer_Base t = (TrailRenderer_Base)serializedObject.targetObject; + if (t == null) + return; + + float defaultLabelWidth = EditorGUIUtility.labelWidth; + float defaultFieldWidth = EditorGUIUtility.fieldWidth; + GUILayout.Space(5); + + GUILayout.BeginVertical(); + + + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.Lifetime")); + EditorGUIUtility.labelWidth = defaultLabelWidth; + EditorGUIUtility.fieldWidth = defaultFieldWidth; + + GUILayout.BeginHorizontal(); + EditorGUIUtility.fieldWidth = defaultLabelWidth - 80; + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.TrailMaterial")); + GUILayout.Space(10); + EditorGUIUtility.labelWidth = 30; + EditorGUIUtility.fieldWidth = 40; + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.MaterialTileLength"), new GUIContent("Tile"), GUILayout.Width(70)); + GUILayout.EndHorizontal(); + + EditorGUIUtility.labelWidth = defaultLabelWidth; + EditorGUIUtility.fieldWidth = defaultFieldWidth; + + + GUILayout.BeginHorizontal(); + EditorGUIUtility.fieldWidth = defaultLabelWidth - 80; + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.SizeOverLife")); + GUILayout.Space(10); + EditorGUIUtility.labelWidth = 50; + EditorGUIUtility.fieldWidth = 20; + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.StretchSizeToFit"), new GUIContent("Stretch"), GUILayout.Width(70)); + GUILayout.EndHorizontal(); + + EditorGUIUtility.labelWidth = defaultLabelWidth; + EditorGUIUtility.fieldWidth = defaultFieldWidth; + + GUILayout.BeginHorizontal(); + EditorGUIUtility.fieldWidth = defaultLabelWidth - 80; + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.ColorOverLife")); + GUILayout.Space(10); + EditorGUIUtility.labelWidth = 50; + EditorGUIUtility.fieldWidth = 20; + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.StretchColorToFit"), new GUIContent("Stretch"), GUILayout.Width(70)); + GUILayout.EndHorizontal(); + EditorGUIUtility.labelWidth = defaultLabelWidth; + EditorGUIUtility.fieldWidth = defaultFieldWidth; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.UseForwardOverride")); + if(t.TrailData.UseForwardOverride) + { + EditorGUI.indentLevel++; + + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.ForwardOverride")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("TrailData.ForwardOverrideRelative"), new GUIContent("Override Relative")); + + + EditorGUI.indentLevel--; + + } + + + DrawTrailSpecificGUI(); + + EditorGUILayout.PropertyField(serializedObject.FindProperty("MaxNumberOfPoints")); + EditorGUILayout.PropertyField(serializedObject.FindProperty("Emit")); + + + GUILayout.EndVertical(); + + + + + serializedObject.ApplyModifiedProperties(); + serializedObject.UpdateIfDirtyOrScript(); + + + GUILayout.Space(5); + if (GUILayout.Button("Open preview")) + { + // Get existing open window or if none, make a new one: + win = (TrailPreviewUtillity)EditorWindow.GetWindow(typeof(TrailPreviewUtillity), true, "Normalized Trail Preview"); + win.minSize = new Vector2(900, 140); + win.maxSize = new Vector2(900, 140); + win.Trail = t; + } + + } + + protected virtual void DrawTrailSpecificGUI() + {} + } +} diff --git a/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs.meta b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs.meta new file mode 100644 index 0000000..95f9b91 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/TrailEditor_Base.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0ab5f16befc58ca4bbfb8159ae3ead06 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs b/Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs new file mode 100644 index 0000000..d8ca78d --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs @@ -0,0 +1,275 @@ +using UnityEngine; +using UnityEditor; + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + public class TrailPreviewUtillity : EditorWindow + { + public TrailRenderer_Base Trail; + + void Update() + { + if (Trail == null || Trail.TrailData == null || Selection.activeGameObject != Trail.gameObject) + { + Close(); + return; + } + + Repaint(); + } + + void OnGUI() + { + if (Trail == null || Trail.TrailData == null) + { + return; + } + + + + GUIStyle blackBG = new GUIStyle(); + blackBG.normal.background = EditorGUIUtility.whiteTexture; + blackBG.normal.textColor = Color.white; + Color revertTo = GUI.color; + + + + float highPoint = 0; + + for (int i = 0; i < 100; i++) + { + float s = Trail.TrailData.SizeOverLife.Evaluate((float)i / (float)100); + if (highPoint < s) + highPoint = s; + } + + GUI.color = new Color(0.3f,0.3f,0.3f,1); + GUILayout.BeginArea(new Rect(0, 0, position.width, position.height), blackBG); + + + float xPos = 0; + float increment = 101; + float modulo = 303; + + while (xPos * increment < position.width) + { + xPos++; + DrawLine(Vector2.right * (xPos * increment), Vector2.right * (xPos * increment) + Vector2.up * position.height, xPos * increment % modulo == 0 ? new Color(1, 1, 1, 0.1f) : new Color(1, 1, 1, 0.025f), 1); + } + + DrawLine(Vector2.up * position.height / 2, Vector2.right * position.width + Vector2.up * position.height / 2, new Color(1, 1, 1, 0.1f), 1); + + + GL.PushMatrix(); + GL.LoadPixelMatrix(-0.5f, 0.5f, 0.5f, -0.5f); + if (Trail.TrailData.TrailMaterial != null) + Trail.TrailData.TrailMaterial.SetPass(0); + + GL.Begin(GL.TRIANGLE_STRIP); + + InsertTriangle(0, 1); + + for (int i = 0; i < 100; i++) + { + InsertTriangle((float)i / (float)100, highPoint * 2); + } + + GL.End(); + GL.PopMatrix(); + + GUILayout.EndArea(); + + if (Trail.TrailData.TrailMaterial == null) + { + GUILayout.BeginVertical(); + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + GUI.color = new Color(0, 0, 0, 0.15f); + + GUILayout.BeginVertical(); + + GUILayout.FlexibleSpace(); + + GUILayout.BeginVertical(blackBG); + GUI.color = Color.white; + GUILayout.Label("Material is NULL", EditorStyles.whiteMiniLabel); + GUILayout.EndVertical(); + GUILayout.FlexibleSpace(); + GUILayout.EndVertical(); + + GUILayout.FlexibleSpace(); + + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + + } + else + { + GUILayout.BeginVertical(); + GUILayout.FlexibleSpace(); + GUILayout.BeginHorizontal(); + GUI.color = new Color(0, 0, 0, 0.15f); + GUILayout.BeginVertical(blackBG); + GUI.color = Color.white; + GUILayout.Label("Start", EditorStyles.whiteMiniLabel); + GUILayout.EndVertical(); + GUILayout.FlexibleSpace(); + + GUI.color = new Color(0, 0, 0, 0.15f); + GUILayout.BeginVertical(blackBG); + GUI.color = Color.white; + GUILayout.Label("End", EditorStyles.whiteMiniLabel); + GUILayout.EndVertical(); + + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + } + + GUI.color = revertTo; + + + } + + void InsertTriangle(float t, float scaler) + { + if(scaler <= 0) + return; + Color c = Trail.TrailData.ColorOverLife.Evaluate(t); + float s = Trail.TrailData.SizeOverLife.Evaluate(t) / (scaler); + + GL.Color(c); + GL.Vertex3(t, 0.5f + s, 0); + GL.MultiTexCoord(0, Trail.TrailData.MaterialTileLength > 0 ? new Vector3((t * position.width) / (300 * Trail.TrailData.MaterialTileLength), 0, 0) : new Vector3(t, 0, 0)); + GL.Vertex3(t, 0.5f - s, 0); + GL.MultiTexCoord(0, Trail.TrailData.MaterialTileLength > 0 ? new Vector3((t * position.width) / (300 * Trail.TrailData.MaterialTileLength), 1, 0) : new Vector3(t, 1, 0)); + } + + public static void DrawLine(Vector2 start, Vector2 end, Color color, float width) + { + if (Event.current == null) + return; + if (Event.current.type != EventType.repaint) + return; + + CreateMaterial(); + + lineMaterial.SetPass(0); + + Vector3 startPt; + Vector3 endPt; + + if (width == 1) + { + GL.Begin(GL.LINES); + GL.Color(color); + startPt = new Vector3(start.x, start.y, 0); + endPt = new Vector3(end.x, end.y, 0); + GL.Vertex(startPt); + GL.Vertex(endPt); + } + else + { + GL.Begin(GL.QUADS); + GL.Color(color); + startPt = new Vector3(end.y, start.x, 0); + endPt = new Vector3(start.y, end.x, 0); + Vector3 perpendicular = (startPt - endPt).normalized * width; + Vector3 v1 = new Vector3(start.x, start.y, 0); + Vector3 v2 = new Vector3(end.x, end.y, 0); + GL.Vertex(v1 - perpendicular); + GL.Vertex(v1 + perpendicular); + GL.Vertex(v2 + perpendicular); + GL.Vertex(v2 - perpendicular); + } + GL.End(); + } + + public static void CreateMaterial() + { + if (lineMaterial != null) + return; + Debug.Log ("Not Supported!{Unity5.0+}"); +// lineMaterial = new Material("Shader \"Lines/Colored Blended\" {" + +// "SubShader { Pass { " + +// " Blend SrcAlpha OneMinusSrcAlpha " + +// " ZWrite Off Cull Off Fog { Mode Off } " + +// " BindChannels {" + +// " Bind \"vertex\", vertex Bind \"color\", color }" + +// "} } }"); +// lineMaterial.hideFlags = HideFlags.HideAndDontSave; +// lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave; + } + + public static Material lineMaterial = null; + + + } +} + +/* +using UnityEngine; +using UnityEditor; + +namespace PigeonCoopToolkit.Effects.Trails.Editor +{ + public class TrailPreviewUtillity : EditorWindow + { + + public PCTrailRendererData Data; + + void OnGUI() + { + if(Data == null) + { + Close(); + return; + } + + DrawLine(Vector2.zero, Vector2.right + Vector2.up,Color.red,1,Data.TrailMaterial); + + } + + public static void DrawLine(Vector2 start, Vector2 end, Color color, float width, Material m) + { + if (Event.current == null) + return; + if (Event.current.type != EventType.repaint) + return; + + + + m.SetPass(0); + + Vector3 startPt; + Vector3 endPt; + + if (width == 1) + { + GL.Begin(GL.LINES); + GL.Color(color); + startPt = new Vector3(start.x, start.y, 0); + endPt = new Vector3(end.x, end.y, 0); + GL.Vertex(startPt); + GL.Vertex(endPt); + } + else + { + GL.Begin(GL.QUADS); + GL.Color(color); + startPt = new Vector3(end.y, start.x, 0); + endPt = new Vector3(start.y, end.x, 0); + Vector3 perpendicular = (startPt - endPt).normalized * width; + Vector3 v1 = new Vector3(start.x, start.y, 0); + Vector3 v2 = new Vector3(end.x, end.y, 0); + GL.Vertex(v1 - perpendicular); + GL.Vertex(v1 + perpendicular); + GL.Vertex(v2 + perpendicular); + GL.Vertex(v2 - perpendicular); + } + GL.End(); + } + + } +} + +*/ \ No newline at end of file diff --git a/Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs.meta b/Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs.meta new file mode 100644 index 0000000..6f9d52b --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Editor/TrailPreviewUtillity.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 34af64ac36cf82046853c1e9e5421c3b +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Icons.meta b/Assets/TrailEffect/Effects/Trails/Icons.meta new file mode 100644 index 0000000..b053e36 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Icons.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: e88319607f0d43843b735c35e8da7d61 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Icons/SmokPlumeIcon.png b/Assets/TrailEffect/Effects/Trails/Icons/SmokPlumeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..a156426253a2d182088349ed680a592955919396 GIT binary patch literal 5129 zcmV+k6!zokUHbhi#L{X8Z2r?+( zfTKf^u_B6v0a3B*1Q|rsac~qHmPur-8Q;8l@6DUvANPK1pS{oBXYYO1x&V;;g9XA& zSP6g(p;#2*=f#MPi)Ua50Sxc}18e}`aI>>Q7WhU2nF4&+jBJ?`_!qsp4j}paD$_rV z!2tiCl(|_VF#u4QjOX(B*<2YH$v8b%oF%tU$(Xh@P0lb%&LUZYGFFpw@+@0?_L*f5 zIrB1vJQ>S#&f;b8cV}o=_hCs$|GJ-ARc>v%@$zSl&FIdda6Uz_9&dgda5+tXH875p)hK-XGi{a1DP3Mcn z%rFi&jU(bQ*qIqw9N}^RX3zXt6nSkKvLZX!I5{{lZ7prSDAa#l{F{>Zc9vd*f9@GX zANa%eSALld0I;TIwb}ZIZD|z%UF!i*yZwjFU@riQvc7c=eQ_STd|pz-;w)z?tK8gN zO97v2DKF^n`kxMeLtlK)Qoh~qM8wF>;&Ay4=AVc79|!(* z9u^V&B)*6*lto0#rc5AAmbF{R6Nm+wLWV&2pPKj&!~Ue%xt59A_z}>SSOTRX8bE#? z04OREAPIY9E70$K3&uwS`OS;bnV6mX&w~DaSGY|6$QC4jj$=neGPn{^&g`1}S^_j6 z07XCp>OdRl0~5dmw!jg%01w~;0zoK<1aV+7;DQv80Yo4d6o9p$7?gsoU?->sb)XS6 zgEnv&bb({wG&lz?fy-b7+yPQB4xWH1@CwX85QK%u5EW8~bRa{>9I}O2kQ?L!1w#=~ z9FzzpLqbRb6+r8tQm7oNhU%ea=v(M0bQ-z<4MVq}QD_qS6?z9FFbSr?TCfpp1+!pJ zI0%k}7s1K!GB_VDg15kxa07f0?u1Xnm*5dt3O|9T5r7a8I--j(5f;KmLXmhR2@xTy zkP@TC$XgT!MMW`COq2`C9~Fh-qL!gnp*EwcQ3p_+s6NzH)F^5S z^$|@*Yog83&gcMiEIJvTi!Mf2pqtPg=(Fe%^f>wz27{qvj4_TFe@q-E6|(}f8M7PH zjyZ)H#*AU6u~@7+)*S1K4aIV>Vr((C3VRTH5_<(Zj(vk8;&gDfIA2^mPKYbSRp451 zCvaDA6Sx_?65bH+j1R^0@XPUK_(psWeh5E~pCKp{j0vuUNJ1)MEuoUoMmS5jOL##f z67`5q#Bid3xQ19sJVZQC93{RbQAlPaHYtH5A#EY;C!HeQBE2A!$wp)kay(f~-a>9B zpCR8TzfqtnSSkc4@Dx@n)F^Z+Tv2$Yh*vaJ^i*7|n6Fr&ctmkX@u?DC$w-N<#8FzM zRHJlM>4ws@GF90|IaE1Ad9!kh@&)Bb6fDJv;zQw4iYWUiXDDM-gsM+vQ@PZ2)JE!A z>NpKUGo}U5QfZ~MZ)k(GDHV!}ol3Myo=T0%aTO^Yp&QWy=;`z_`eFKY`a4xERZmsE z>L%4T)hnv6)#j*qsPWZG)Y{cX)ZVEx)P2;`)VHa3so&E;X_#q*YvgL|(KxH|bPjEf z%N*{Uk~xRx+}4CO%`_u4S7`3j9MGKB($@0R%F?RRI-~Veo38DlovOV<`-JwS4pqlZ zN1(Gq=cLYKh6=-zkLZ@rEqJ6vJJH{f4iNjE!Q9HW+moJu+4^4lvF)ZZ*DZLN;+XS!U8; za?KQD$}&we-EDf=3^ubjOEIf48#0H@9n1yhyUm9!&=yV>LW>5A8%z?@lbOS8WsX|X zErTr!ExRnASs7TxTWz!IxB6&pZ=G)4Xnn_qViRanXwzf!tF4(W*S5y?+FbHn-?^*j zcF%ooXKu&0+hcdro@yUrzrnuO{)2;~gUF%HVbamSG10Ns@dk^=3S(_%op(Yzc{#0i zI_C7&*}+-teAxLH7p6;^ON+~+dB*ej^BU)kx$3!cTZVb0Xx4mvscU^amdxQG} z4}A}wN0Y~dr>SSE=RwbBUe;bBuMV%*Y-jdL_9<_~+t0hid(emC6XjFwbKh6bH`%w< zcgoM+Z-w6}f3$y)|2F>{0a^jvfaZXyK*zw9fqg-wpantIK@Wn>fV8I2F~=-fTgudr?_nHF76Ya2X6;&lJCkd z=T9WLCY2{WN_I`&o;;c2o>GzWRKONg3!bO?r`DyuP76)jpY|y|CcQlamywupR7eq~ z3Hvg&GxIWsv&^%Kv!u(Mm+f3OB?=NXWkcDEvb)7J+0WE~#6+@QGMeL-QhTd=lZbfxFY`c=@XrK@^Z>#r_aJ-)_o&4IOq zwP|aAD6}ptFMPQ!W?fH_R?(WGvGsoITZV0)e^+=6ZO?$0o?WWq-yLr2>?D5#sR;N{0 zTK8_RVDHU(zxvJwqlSuon0-0>9yUfd_J7U#y17ZCskG_Ce&K%UfrtZr&5q5@Et)N5 zt#GTPb@E`s!OP!xf79K@Y^!glx0fCQha`s{f1CL2^}|7jdylY=w0&pzU2O-oqofn+ zT;4g=mC_~cj_V#i8hEs~$EBy^d&}?lAJaWnb6n+k*$Kjlq7$D^=AWECm38Xr>EzR6 zy-RxUoQXYituMT9@NCf8^XGieo$2@NKY8Bu{ILtp7mi+JUF^E#aH(^^exTzA`yV<6 z9R@px9EZ9uJ6-M>o;Q5riu;w*SG}*EyB2Wm(#ZUg;pqt>?FM zZqM9Va~FNLGD$lbNT*KP&%S`^@CocfWZ2GB6c8HU3=m{L`|I+Sd z?{wJo{Z|>UW?q-PQGavbE$eOnyO?(qGr8}v?<+r;e(3oa^zrVej8C6_1NVgU`|$@E zjQ{`u32;bRa{vGf5&!@T5&_cPe*6Fc35H2TK~#9!?OkbXR8tRBBB)3a z0fTWbtDs0U{t$4B7>yeVl4z^`FlyowYfSWqlK4XtV~jB|5)GmOVl1G>UD=CES(K#& zK~!XE$Mf}`f$1>Q&U>9s-#ho5xLf)PNU9AdOE1~MLJOl4HCbubIy zfk5#a7~AFE`!i~V3`rkJ;2Qy8)3=HLhm?b*GWp4EtQO08AE+|KE4tlT@Tot!31wr6#j4G%DT0ky>;p9zqX7~tC+ z>0sIljA(TOit7SC6Cj-qq8`wk=jW#|#)~yb7yz9X0TG-GIQOp9w+zsq%$HXHGxRP;_xd5GlUBNAR0>Sh% z8cA+{AYla1C;Q3u2jn9_LSle^5)&8!lnF9`iVjvc+(4zq=cPUf%r4tzMeGU6^y4Crw3F%I)zpUalX;+A2nKl zbU)vG#*lzM9})ke)|Ky+f4~S3ztxY^J!s~v4tRgfvhwFq+vDS^MPn9#29E0``Y$+^ zB-a}Duusa@NC2#O6nn-7^!rdc<^_FEo{0(qWSIX!V*XDI@Nu+*J^FjLdu<~axCXlCxWVGBgl#WB58z^|=CfdZNOBz|`8v!&G zf>6_6D}FslHh|y7*6}E*3+(eLBhX~_pg1&fY!C5S)DP}soJ}6QM@cII5C~$3!!im! z$e~9qx!pzeu0Uf~F#P`tNeRaVT*>%dl!otM{Kj~n>gso8 z#}pu32g9e#0(5gt0LojMPU%8s1vmmSje<3o8UZ3A|A`f7pl~O8({q7pB|GSo`K&b6 z2-FZDYcC&4|AFy=kRgn~|DVUWmt2=|PqP5=k|rSlW&wwt?130*lmvx+i~#Wx6o!6f zyeH{lSiyuaOcfcX(F&*{0Ng;9D?lo^Na_NqPFMld2heVQyrqE=lLBS|fOrWSMX*V{GJ-M* z1{0brfG>k0%O!y$6xf@NoKQ7cv${Iy9TL36}fGEF)f=>*~6-e$RWn<&D27y?m7!)z1NXjQ!{YWME zYa&4WOToF#K28ebe859RQhqvvSSti*F$)mgm5)e$3gZ!SmAhiyBb2|1l#Ptn76TyF zyNvM|xn_=HC_f$ieMRp5f<}Odu6*p(j}xCix`@#_l#k-ka&ZHy-WsCC1;FoPLg*aE zW_W-z3TVi*-*p z3-BGeZR8&*d~>PA09`Ct@pui~2r6FB9#;OBjOWDn?<1w6!2%%iN59^{BAI?v`j$v0 zu~K4ywrPQ)adH|g04952m#0Xzd93&ardD5qz}jjk9n(M>88c1!{#gJBM#DY8%3qx` zNND?VX;cgGO4)13^$iS`?{Aj$54(P-{vFx)(J~82uhi8iq2zXuU`$}FOBF5~&*Mz*5M1ay^K# zcL7=mfC}IC5?>ngf_7L85Dn>$F3oC-0iq+5J-Mb4AdgJwrl8Y;z=*^EIJi;j7dzlR zg_RZqm>2;fAX`1TrV${IeCEkDjR1LMX*XPRnFWE-2?DJU1P)okUHbhi#L{X8Z2r?+( zfTKf^u_B6v0a3B*1Q|rsac~qHmPur-8Q;8l@6DUvANPK1pS{oBXYYO1x&V;;g9XA& zSP6g(p;#2*=f#MPi)Ua50Sxc}18e}`aI>>Q7WhU2nF4&+jBJ?`_!qsp4j}paD$_rV z!2tiCl(|_VF#u4QjOX(B*<2YH$v8b%oF%tU$(Xh@P0lb%&LUZYGFFpw@+@0?_L*f5 zIrB1vJQ>S#&f;b8cV}o=_hCs$|GJ-ARc>v%@$zSl&FIdda6Uz_9&dgda5+tXH875p)hK-XGi{a1DP3Mcn z%rFi&jU(bQ*qIqw9N}^RX3zXt6nSkKvLZX!I5{{lZ7prSDAa#l{F{>Zc9vd*f9@GX zANa%eSALld0I;TIwb}ZIZD|z%UF!i*yZwjFU@riQvc7c=eQ_STd|pz-;w)z?tK8gN zO97v2DKF^n`kxMeLtlK)Qoh~qM8wF>;&Ay4=AVc79|!(* z9u^V&B)*6*lto0#rc5AAmbF{R6Nm+wLWV&2pPKj&!~Ue%xt59A_z}>SSOTRX8bE#? z04OREAPIY9E70$K3&uwS`OS;bnV6mX&w~DaSGY|6$QC4jj$=neGPn{^&g`1}S^_j6 z07XCp>OdRl0~5dmw!jg%01w~;0zoK<1aV+7;DQv80Yo4d6o9p$7?gsoU?->sb)XS6 zgEnv&bb({wG&lz?fy-b7+yPQB4xWH1@CwX85QK%u5EW8~bRa{>9I}O2kQ?L!1w#=~ z9FzzpLqbRb6+r8tQm7oNhU%ea=v(M0bQ-z<4MVq}QD_qS6?z9FFbSr?TCfpp1+!pJ zI0%k}7s1K!GB_VDg15kxa07f0?u1Xnm*5dt3O|9T5r7a8I--j(5f;KmLXmhR2@xTy zkP@TC$XgT!MMW`COq2`C9~Fh-qL!gnp*EwcQ3p_+s6NzH)F^5S z^$|@*Yog83&gcMiEIJvTi!Mf2pqtPg=(Fe%^f>wz27{qvj4_TFe@q-E6|(}f8M7PH zjyZ)H#*AU6u~@7+)*S1K4aIV>Vr((C3VRTH5_<(Zj(vk8;&gDfIA2^mPKYbSRp451 zCvaDA6Sx_?65bH+j1R^0@XPUK_(psWeh5E~pCKp{j0vuUNJ1)MEuoUoMmS5jOL##f z67`5q#Bid3xQ19sJVZQC93{RbQAlPaHYtH5A#EY;C!HeQBE2A!$wp)kay(f~-a>9B zpCR8TzfqtnSSkc4@Dx@n)F^Z+Tv2$Yh*vaJ^i*7|n6Fr&ctmkX@u?DC$w-N<#8FzM zRHJlM>4ws@GF90|IaE1Ad9!kh@&)Bb6fDJv;zQw4iYWUiXDDM-gsM+vQ@PZ2)JE!A z>NpKUGo}U5QfZ~MZ)k(GDHV!}ol3Myo=T0%aTO^Yp&QWy=;`z_`eFKY`a4xERZmsE z>L%4T)hnv6)#j*qsPWZG)Y{cX)ZVEx)P2;`)VHa3so&E;X_#q*YvgL|(KxH|bPjEf z%N*{Uk~xRx+}4CO%`_u4S7`3j9MGKB($@0R%F?RRI-~Veo38DlovOV<`-JwS4pqlZ zN1(Gq=cLYKh6=-zkLZ@rEqJ6vJJH{f4iNjE!Q9HW+moJu+4^4lvF)ZZ*DZLN;+XS!U8; za?KQD$}&we-EDf=3^ubjOEIf48#0H@9n1yhyUm9!&=yV>LW>5A8%z?@lbOS8WsX|X zErTr!ExRnASs7TxTWz!IxB6&pZ=G)4Xnn_qViRanXwzf!tF4(W*S5y?+FbHn-?^*j zcF%ooXKu&0+hcdro@yUrzrnuO{)2;~gUF%HVbamSG10Ns@dk^=3S(_%op(Yzc{#0i zI_C7&*}+-teAxLH7p6;^ON+~+dB*ej^BU)kx$3!cTZVb0Xx4mvscU^amdxQG} z4}A}wN0Y~dr>SSE=RwbBUe;bBuMV%*Y-jdL_9<_~+t0hid(emC6XjFwbKh6bH`%w< zcgoM+Z-w6}f3$y)|2F>{0a^jvfaZXyK*zw9fqg-wpantIK@Wn>fV8I2F~=-fTgudr?_nHF76Ya2X6;&lJCkd z=T9WLCY2{WN_I`&o;;c2o>GzWRKONg3!bO?r`DyuP76)jpY|y|CcQlamywupR7eq~ z3Hvg&GxIWsv&^%Kv!u(Mm+f3OB?=NXWkcDEvb)7J+0WE~#6+@QGMeL-QhTd=lZbfxFY`c=@XrK@^Z>#r_aJ-)_o&4IOq zwP|aAD6}ptFMPQ!W?fH_R?(WGvGsoITZV0)e^+=6ZO?$0o?WWq-yLr2>?D5#sR;N{0 zTK8_RVDHU(zxvJwqlSuon0-0>9yUfd_J7U#y17ZCskG_Ce&K%UfrtZr&5q5@Et)N5 zt#GTPb@E`s!OP!xf79K@Y^!glx0fCQha`s{f1CL2^}|7jdylY=w0&pzU2O-oqofn+ zT;4g=mC_~cj_V#i8hEs~$EBy^d&}?lAJaWnb6n+k*$Kjlq7$D^=AWECm38Xr>EzR6 zy-RxUoQXYituMT9@NCf8^XGieo$2@NKY8Bu{ILtp7mi+JUF^E#aH(^^exTzA`yV<6 z9R@px9EZ9uJ6-M>o;Q5riu;w*SG}*EyB2Wm(#ZUg;pqt>?FM zZqM9Va~FNLGD$lbNT*KP&%S`^@CocfWZ2GB6c8HU3=m{L`|I+Sd z?{wJo{Z|>UW?q-PQGavbE$eOnyO?(qGr8}v?<+r;e(3oa^zrVej8C6_1NVgU`|$@E zjQ{`u32;bRa{vGf5&!@T5&_cPe*6Fc3I$0-K~#9!?Oj=HRAm%C!*r!BvdE@FDPfUK zK@BcI!QChtm#}E!o6#6ed}`l(Gd@6!%A>xSsHiAz2+9`PsE8nHWfO!70wPqPKq=GZ zdOq*D;Zo+#y>#wO=l=J6$w{ZP-I@P<|JnZY|3jouC=?2XLZMJ76bgkxp-?Ck3WY+U zP$pHqK%Esn>XZP5>EnCK0xNe|7zP0} z3&>rRkEs679ACbgvxI}$yg@%zVb0R))p@wiYOm}dsEben|(h-Pak17%Op<)ClX44JQDyFzQ6PQF-EW)>kR?a1%!_|eQ?cM4FU@XcSq@(N`UY& zuaAOG4FU@!1~|h~ndgsjmZeH#0EN1M0>EEUx~38!d~Ax+HI)G2V_hFybG-(Eg%bou zst{D9D)hmU2EPf^lL1h~UY7BB`h>f^l&>xzx54uumTNs8e>RVw<@s!0tQO$P6^|Sr z3q6lW?){QSP_~nDzaqFh+n`fpfZ#5mjAabVeJl%EX0Rk-1+2O`Eook<4Izf0Sd{q$ z%j+z!lHJeWpQV)LMUU4(F^h8exfaPaNG(8af;=dG7}>S`C&{k2rz`QEVwuQR;2)3o zsl!!5{?zp>OM^uD8Uyrh#v_%xljSLvJ6Hx}c>X|^Wh{$59*3e1vAiGB=K~p+hZ)o; zE-HSMDDo|qH^ko$2x5*COB-Lv@HiA!ErDTgu~Xh-d6-{X31BP!I`Q$C$*+mx2Vdd% zyvZbZJj3Jg*Hc;Uk~%?9?3LF{4a4WhF9z`T@o;}bSZ0dy?-8G0l*PDou`J+tV5Q@m zeKv=pd+2^~Gh^ibW|r?*zGi96_2$qx#sEq2+tXMcW|_}YBbFc=bh022e2gu@7XEwK zCrE>0SBUf(;zoc9MC_vUN2O3xn&o?9)}JJMOZRe_y(gkFAaNl;3E8#z`BKE0D)(gr z*!I&bKeD_>c0~@eJ{6^bi9P``FV>VwVv7lABmQX8DTc0NEY5#=s;3plE|i-ZNP$-;zLXKg%kX z&&aOAq2}Lhny)M}?7K`93s97W;$hx5u&k6o@1&%9M#3ZlpujVhdbcT~Q&PAMV(zy| zF5k&Pp3(WSNd&OSV|PpjU}mF%6P>&(B&Tl?Lc{{55#YS|>12TC!?b@+_A>2H@_%d; zZz2IYWHz@;>gSi%y~6Si%fBWDcX1>Dl=!>&Za)H`8i>MBEBpA^D&I++Oaj)+e+?Kg zBDxz!F^6e|Aoy`C4m{`+2cR-Ig|H;Nq~SqxZu#Wbg1PQv#R+ z6m#~7_@#JI{H@$1)0L7y}f1nb;EF34heJjWU&rOuS6Frmwc>;<;jS>&|0cY&YrtJ3!C;lY|eSFxd)8X?x6ot?_J}qw9fazZrZUC!;LDvSbNwXqO1c-j> zlX z`m0%PknF+O(r_p)K$P#C&ofSnDKMcEgannM(4;6cna0dpy|hTVvSRqW)$*N`00Dqm zi#2upTuQCXKAgnq7%sP%< zooR^j0h~3kN6f!vDgnZ>0LYu~B{Mc!I)_DlLw0NVS(7b5SOh>v?N~#`1a*QhSl(vY z$7x=t62Ko*C^tWu-rLN;>%E-6ogyd;WA_j?lAu)l8`&p?p^xw|8FCtEP6@y%AmWG{ zLx?B3=+e?{KbP`*62X$^I|nph5M{x1x5@vlGMmqcw2GXQ=cGiiQg})Ta6)dUC?@9y zg<%0usJW7ETFa$y_*bmeAC;i%q&!|K`FEu}uTvC<1D#I0lsj&LI@|_X0QTXS_2VgXcMXEL4=LED3`GQ80Cv<4$l&`C^sVOE-=#xs9s%&$ z8uIR+NAU&iRQq+9%_Kll{C~Ot5HlXTazCQ_+7xnqFHuC70A(H-fF%+CDhU7;h7thE zACcxgun_YzQa|?n7j%ftB>);eho+hR*m!}TKHsjxYbXIE1)P*71Hd8;PU!qnBY(3k z018NB=+Ylz?v}Lg0|@{X1{0u|E-wI~kpg{m>vZ-TOaL+e*fcTRl>xx??;yM8-=f26 zz6BWCBLg@gvwySJ{Nq6Y{6_B(*X&2yw~CeDu0t9R0$>fGN&>$_V)}RJaK?iG2mq@k z6F`^kCYH54`%^lc@gRWH1cE+4Y@Pa)>>hfB=>(7r0NcN?cOEU=IFG+U)4rGxfE8^? z^bZ2y#I3Ky4Jcw{0VYV~kDp%Oj=p-F(ZJ?c8lzF{^L4y@pJ)b^KMepuTUry3WY)uZTtt-#y+{N3S8^} O0000k0)HzmB1O-l+x`X+l!cji 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 literal 0 HcmV?d00001 diff --git a/Assets/TrailEffect/Effects/Trails/PCTrail.cs b/Assets/TrailEffect/Effects/Trails/PCTrail.cs new file mode 100644 index 0000000..ddab263 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/PCTrail.cs @@ -0,0 +1,60 @@ +using PigeonCoopToolkit.Utillities; +using System; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace PigeonCoopToolkit.Effects.Trails +{ + public class PCTrail : IDisposable + { + public CircularBuffer Points; + + public Mesh Mesh; + + public Vector3[] verticies; + + public Vector3[] normals; + + public Vector2[] uvs; + + public Color[] colors; + + public int[] indicies; + + public int activePointCount; + + public bool IsActiveTrail; + + public int NumPoints; + + public PCTrail(int numPoints) + { + this.Mesh = new Mesh(); + this.Mesh.MarkDynamic(); + this.verticies = new Vector3[2 * numPoints]; + this.normals = new Vector3[2 * numPoints]; + this.uvs = new Vector2[2 * numPoints]; + this.colors = new Color[2 * numPoints]; + this.indicies = new int[2 * numPoints * 3]; + this.Points = new CircularBuffer(numPoints); + this.NumPoints = numPoints; + } + + public void Dispose() + { + if (this.Mesh != null) + { + if (Application.isEditor) + { + Object.DestroyImmediate(this.Mesh, true); + } + else + { + Object.Destroy(this.Mesh); + } + } + this.Points.Clear(); + this.Points = null; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/PCTrail.cs.meta b/Assets/TrailEffect/Effects/Trails/PCTrail.cs.meta new file mode 100644 index 0000000..7875d73 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/PCTrail.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 6bdb573c1d60b9b4c9c5813da7dd36b3 +timeCreated: 1510298205 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs b/Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs new file mode 100644 index 0000000..f551e28 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; + +namespace PigeonCoopToolkit.Effects.Trails +{ + public class PCTrailPoint + { + public Vector3 Forward; + + public Vector3 Position; + + public int PointNumber; + + private float _timeActive; + + private float _distance; + + public virtual void Update(float deltaTime) + { + this._timeActive += deltaTime; + } + + public float TimeActive() + { + return this._timeActive; + } + + public void SetTimeActive(float time) + { + this._timeActive = time; + } + + public void SetDistanceFromStart(float distance) + { + this._distance = distance; + } + + public float GetDistanceFromStart() + { + return this._distance; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs.meta b/Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs.meta new file mode 100644 index 0000000..e80c01d --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/PCTrailPoint.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d1183b720c636c54187be6b54124b9d8 +timeCreated: 1510298399 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs b/Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs new file mode 100644 index 0000000..26df792 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs @@ -0,0 +1,41 @@ +using System; +using UnityEngine; + +namespace PigeonCoopToolkit.Effects.Trails +{ + [Serializable] + public class PCTrailRendererData + { + public Material TrailMaterial; + + public float Lifetime = 1f; + + public bool UsingSimpleSize; + + public float SimpleSizeOverLifeStart; + + public float SimpleSizeOverLifeEnd; + + public AnimationCurve SizeOverLife = new AnimationCurve(); + + public bool UsingSimpleColor; + + public Color SimpleColorOverLifeStart; + + public Color SimpleColorOverLifeEnd; + + public Gradient ColorOverLife; + + public bool StretchSizeToFit; + + public bool StretchColorToFit; + + public float MaterialTileLength; + + public bool UseForwardOverride; + + public Vector3 ForwardOverride; + + public bool ForwardOverrideRelative; + } +} diff --git a/Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs.meta b/Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs.meta new file mode 100644 index 0000000..931dc15 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/PCTrailRendererData.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2df86c9fa942e934f8d1b47514ebeeca +timeCreated: 1510298132 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/Resources.meta b/Assets/TrailEffect/Effects/Trails/Resources.meta new file mode 100644 index 0000000..256089d --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Resources.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 6f284d34362cfbd4dac1f041e217159f +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Resources/PCTK.meta b/Assets/TrailEffect/Effects/Trails/Resources/PCTK.meta new file mode 100644 index 0000000..787e14e --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Resources/PCTK.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: cb26a4a5e9479484ea1e4015d6117887 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects.meta b/Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects.meta new file mode 100644 index 0000000..0f440bd --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f4c3d22dfd9259b47bd18e2fbb40a661 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects/Trails.meta b/Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects/Trails.meta new file mode 100644 index 0000000..ddc0226 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Resources/PCTK/Effects/Trails.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 9c92f0fb3caf95948bab8c97c7c38a7d +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Effects/Trails/SmokePlume.cs b/Assets/TrailEffect/Effects/Trails/SmokePlume.cs new file mode 100644 index 0000000..17e2587 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmokePlume.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using Random = UnityEngine.Random; + +namespace PigeonCoopToolkit.Effects.Trails +{ + [AddComponentMenu("Pigeon Coop Toolkit/Effects/Smoke Plume")] + public class SmokePlume : TrailRenderer_Base + { + public float TimeBetweenPoints = 0.1f; + + public Vector3 ConstantForce = Vector3.up * 0.5f; + + public float RandomForceScale = 0.05f; + + public int MaxNumberOfPoints = 50; + + private float _timeSincePoint; + + protected void OnEnable() + { + base.Start(); + base.ClearSystem(true); + this._timeSincePoint = 0f; + } + + protected override void OnStartEmit() + { + this._timeSincePoint = 0f; + } + + protected override void Reset() + { + base.Reset(); + this.TrailData.SizeOverLife = new AnimationCurve(new Keyframe[] + { + new Keyframe(0f, 0f), + new Keyframe(0.5f, 0.2f), + new Keyframe(1f, 0.2f) + }); + this.TrailData.Lifetime = 6f; + this.ConstantForce = Vector3.up * 0.5f; + this.TimeBetweenPoints = 0.1f; + this.RandomForceScale = 0.05f; + this.MaxNumberOfPoints = 50; + } + + protected override void Update() + { + if (this._emit) + { + this._timeSincePoint += (this._noDecay ? 0f : Time.deltaTime); + if (this._timeSincePoint >= this.TimeBetweenPoints) + { + base.AddPoint(new SmokeTrailPoint(), this._t.position); + this._timeSincePoint = 0f; + } + } + base.Update(); + } + + protected override void InitialiseNewPoint(PCTrailPoint newPoint) + { + ((SmokeTrailPoint)newPoint).RandomVec = Random.onUnitSphere * this.RandomForceScale; + } + + protected override void UpdateTrail(PCTrail trail, float deltaTime) + { + if (this._noDecay) + { + return; + } + + using IEnumerator enumerator = trail.Points.GetEnumerator(); + while (enumerator.MoveNext()) + { + PCTrailPoint current = enumerator.Current; + current.Position += this.ConstantForce * deltaTime; + } + } + + protected override int GetMaxNumberOfPoints() + { + return this.MaxNumberOfPoints; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/SmokePlume.cs.meta b/Assets/TrailEffect/Effects/Trails/SmokePlume.cs.meta new file mode 100644 index 0000000..d395369 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmokePlume.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 9150799c728c3564980a1475e0a0808c +timeCreated: 1510298265 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/SmokeTrail.cs b/Assets/TrailEffect/Effects/Trails/SmokeTrail.cs new file mode 100644 index 0000000..0819fd8 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmokeTrail.cs @@ -0,0 +1,70 @@ +using System; +using UnityEngine; +using Random = UnityEngine.Random; + +namespace PigeonCoopToolkit.Effects.Trails +{ + [AddComponentMenu("Pigeon Coop Toolkit/Effects/Smoke Trail")] + public class SmokeTrail : TrailRenderer_Base + { + public float MinVertexDistance = 0.1f; + + public int MaxNumberOfPoints = 50; + + private Vector3 _lastPosition; + + private float _distanceMoved; + + public float RandomForceScale = 1f; + + protected void OnEnable() + { + base.Start(); + base.ClearSystem(true); + this._lastPosition = this._t.position; + } + + protected override void Update() + { + if (this._emit) + { + this._distanceMoved += Vector3.Distance(this._t.position, this._lastPosition); + if (this._distanceMoved != 0f && this._distanceMoved >= this.MinVertexDistance) + { + base.AddPoint(new SmokeTrailPoint(), this._t.position); + this._distanceMoved = 0f; + } + this._lastPosition = this._t.position; + } + base.Update(); + } + + protected override void OnStartEmit() + { + this._lastPosition = this._t.position; + this._distanceMoved = 0f; + } + + protected override void Reset() + { + base.Reset(); + this.MinVertexDistance = 0.1f; + this.RandomForceScale = 1f; + } + + protected override void InitialiseNewPoint(PCTrailPoint newPoint) + { + ((SmokeTrailPoint)newPoint).RandomVec = Random.onUnitSphere * this.RandomForceScale; + } + + protected override void OnTranslate(Vector3 t) + { + this._lastPosition += t; + } + + protected override int GetMaxNumberOfPoints() + { + return this.MaxNumberOfPoints; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/SmokeTrail.cs.meta b/Assets/TrailEffect/Effects/Trails/SmokeTrail.cs.meta new file mode 100644 index 0000000..49e8180 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmokeTrail.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: e6e5843f68b0854409013b4b9196c5fd +timeCreated: 1510298456 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs b/Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs new file mode 100644 index 0000000..8adebed --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs @@ -0,0 +1,16 @@ +using System; +using UnityEngine; + +namespace PigeonCoopToolkit.Effects.Trails +{ + public class SmokeTrailPoint : PCTrailPoint + { + public Vector3 RandomVec; + + public override void Update(float deltaTime) + { + base.Update(deltaTime); + this.Position += this.RandomVec * deltaTime; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs.meta b/Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs.meta new file mode 100644 index 0000000..fd47624 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmokeTrailPoint.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2cd086e711bdc064f8bc07309eedeb68 +timeCreated: 1510298131 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/SmoothTrail.cs b/Assets/TrailEffect/Effects/Trails/SmoothTrail.cs new file mode 100644 index 0000000..58b850a --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmoothTrail.cs @@ -0,0 +1,188 @@ +using PigeonCoopToolkit.Utillities; +using System; +using UnityEngine; + +namespace PigeonCoopToolkit.Effects.Trails +{ + [AddComponentMenu("Pigeon Coop Toolkit/Effects/Smooth Trail")] + public class SmoothTrail : TrailRenderer_Base + { + private class ControlPoint + { + public Vector3 p; + + public Vector3 forward; + } + + public float MinControlPointDistance = 0.1f; + + public int MaxControlPoints = 15; + + public int PointsBetweenControlPoints = 4; + + private Vector3 _lastPosition; + + private float _distanceMoved; + + private CircularBuffer _controlPoints; + + protected void OnEnable() + { + base.Start(); + base.ClearSystem(true); + this._lastPosition = this._t.position; + } + + protected override void Update() + { + if (this._emit) + { + this._distanceMoved += Vector3.Distance(this._t.position, this._lastPosition); + if (!Mathf.Approximately(this._distanceMoved, 0f) && this._distanceMoved >= this.MinControlPointDistance) + { + this.AddControlPoint(this._t.position); + this._distanceMoved = 0f; + } + else + { + this._controlPoints[this._controlPoints.Count - 1].p = this._t.position; + if (this.TrailData.UseForwardOverride) + { + this._controlPoints[this._controlPoints.Count - 1].forward = (this.TrailData.ForwardOverrideRelative ? this._t.TransformDirection(this.TrailData.ForwardOverride.normalized) : this.TrailData.ForwardOverride.normalized); + } + } + this._lastPosition = this._t.position; + } + base.Update(); + } + + protected override void OnStartEmit() + { + this._lastPosition = this._t.position; + this._distanceMoved = 0f; + this._controlPoints = new CircularBuffer(this.MaxControlPoints); + this._controlPoints.Add(new SmoothTrail.ControlPoint + { + p = this._lastPosition + }); + if (this.TrailData.UseForwardOverride) + { + this._controlPoints[0].forward = (this.TrailData.ForwardOverrideRelative ? this._t.TransformDirection(this.TrailData.ForwardOverride.normalized) : this.TrailData.ForwardOverride.normalized); + } + base.AddPoint(new PCTrailPoint(), this._lastPosition); + this.AddControlPoint(this._lastPosition); + } + + protected override void UpdateTrail(PCTrail trail, float deltaTime) + { + if (!trail.IsActiveTrail) + { + return; + } + int num = 0; + for (int i = 0; i < this._controlPoints.Count; i++) + { + trail.Points[num].Position = this._controlPoints[i].p; + if (this.TrailData.UseForwardOverride) + { + trail.Points[num].Forward = this._controlPoints[i].forward; + } + num++; + if (i < this._controlPoints.Count - 1) + { + float d = Vector3.Distance(this._controlPoints[i].p, this._controlPoints[i + 1].p) / 2f; + Vector3 curveStartHandle; + if (i == 0) + { + curveStartHandle = this._controlPoints[i].p + (this._controlPoints[i + 1].p - this._controlPoints[i].p).normalized * d; + } + else + { + curveStartHandle = this._controlPoints[i].p + (this._controlPoints[i + 1].p - this._controlPoints[i - 1].p).normalized * d; + } + int num2 = i + 1; + Vector3 curveEndHandle; + if (num2 == this._controlPoints.Count - 1) + { + curveEndHandle = this._controlPoints[num2].p + (this._controlPoints[num2 - 1].p - this._controlPoints[num2].p).normalized * d; + } + else + { + curveEndHandle = this._controlPoints[num2].p + (this._controlPoints[num2 - 1].p - this._controlPoints[num2 + 1].p).normalized * d; + } + PCTrailPoint pCTrailPoint = trail.Points[num - 1]; + PCTrailPoint pCTrailPoint2 = trail.Points[num - 1 + this.PointsBetweenControlPoints + 1]; + for (int j = 0; j < this.PointsBetweenControlPoints; j++) + { + float t = ((float)j + 1f) / ((float)this.PointsBetweenControlPoints + 1f); + trail.Points[num].Position = this.GetPointAlongCurve(this._controlPoints[i].p, curveStartHandle, this._controlPoints[i + 1].p, curveEndHandle, t, 0.3f); + trail.Points[num].SetTimeActive(Mathf.Lerp(pCTrailPoint.TimeActive(), pCTrailPoint2.TimeActive(), t)); + if (this.TrailData.UseForwardOverride) + { + trail.Points[num].Forward = Vector3.Lerp(pCTrailPoint.Forward, pCTrailPoint2.Forward, t); + } + num++; + } + } + } + int num3 = this._controlPoints.Count - 1 + (this._controlPoints.Count - 1) * this.PointsBetweenControlPoints; + int num4 = num3 - this.PointsBetweenControlPoints - 1; + int num5 = num3 + 1; + float num6 = trail.Points[num4].GetDistanceFromStart(); + for (int k = num4 + 1; k < num5; k++) + { + num6 += Vector3.Distance(trail.Points[k - 1].Position, trail.Points[k].Position); + trail.Points[k].SetDistanceFromStart(num6); + } + } + + protected override void Reset() + { + base.Reset(); + this.MinControlPointDistance = 0.1f; + this.MaxControlPoints = 15; + this.PointsBetweenControlPoints = 4; + } + + protected override void OnTranslate(Vector3 t) + { + this._lastPosition += t; + for (int i = 0; i < this._controlPoints.Count; i++) + { + this._controlPoints[i].p += t; + } + } + + private void AddControlPoint(Vector3 position) + { + for (int i = 0; i < this.PointsBetweenControlPoints; i++) + { + base.AddPoint(new PCTrailPoint(), position); + } + base.AddPoint(new PCTrailPoint(), position); + SmoothTrail.ControlPoint controlPoint = new SmoothTrail.ControlPoint + { + p = position + }; + if (this.TrailData.UseForwardOverride) + { + controlPoint.forward = (this.TrailData.ForwardOverrideRelative ? this._t.TransformDirection(this.TrailData.ForwardOverride.normalized) : this.TrailData.ForwardOverride.normalized); + } + this._controlPoints.Add(controlPoint); + } + + protected override int GetMaxNumberOfPoints() + { + return this.MaxControlPoints + this.MaxControlPoints * this.PointsBetweenControlPoints; + } + + public Vector3 GetPointAlongCurve(Vector3 curveStart, Vector3 curveStartHandle, Vector3 curveEnd, Vector3 curveEndHandle, float t, float crease) + { + float num = 1f - t; + float num2 = Mathf.Pow(num, 3f); + float num3 = Mathf.Pow(num, 2f); + float num4 = 1f - crease; + return (num2 * curveStart * num4 + 3f * num3 * t * curveStartHandle * crease + 3f * num * Mathf.Pow(t, 2f) * curveEndHandle * crease + Mathf.Pow(t, 3f) * curveEnd * num4) / (num2 * num4 + 3f * num3 * t * crease + 3f * num * Mathf.Pow(t, 2f) * crease + Mathf.Pow(t, 3f) * num4); + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/SmoothTrail.cs.meta b/Assets/TrailEffect/Effects/Trails/SmoothTrail.cs.meta new file mode 100644 index 0000000..1cd2898 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/SmoothTrail.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: fd5b6425a33ee3749a6a773b54f07066 +timeCreated: 1510298520 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/Trail.cs b/Assets/TrailEffect/Effects/Trails/Trail.cs new file mode 100644 index 0000000..276cf33 --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Trail.cs @@ -0,0 +1,61 @@ +using System; +using UnityEngine; + +namespace PigeonCoopToolkit.Effects.Trails +{ + [AddComponentMenu("Pigeon Coop Toolkit/Effects/Trail")] + public class Trail : TrailRenderer_Base + { + public float MinVertexDistance = 0.1f; + + public int MaxNumberOfPoints = 50; + + private Vector3 _lastPosition; + + private float _distanceMoved; + + public void OnEnable() + { + base.Start(); + base.ClearSystem(true); + this._lastPosition = this._t.position; + } + + protected override void Update() + { + if (this._emit) + { + this._distanceMoved += Vector3.Distance(this._t.position, this._lastPosition); + if (this._distanceMoved != 0f && this._distanceMoved >= this.MinVertexDistance) + { + base.AddPoint(new PCTrailPoint(), this._t.position); + this._distanceMoved = 0f; + } + this._lastPosition = this._t.position; + } + base.Update(); + } + + protected override void OnStartEmit() + { + this._lastPosition = this._t.position; + this._distanceMoved = 0f; + } + + protected override void Reset() + { + base.Reset(); + this.MinVertexDistance = 0.1f; + } + + protected override void OnTranslate(Vector3 t) + { + this._lastPosition += t; + } + + protected override int GetMaxNumberOfPoints() + { + return this.MaxNumberOfPoints; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/Trail.cs.meta b/Assets/TrailEffect/Effects/Trails/Trail.cs.meta new file mode 100644 index 0000000..fce64df --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/Trail.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 3f6ff3d33c169d34ca9bc146f4ef62ce +timeCreated: 1510298149 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs b/Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs new file mode 100644 index 0000000..c07be6d --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs @@ -0,0 +1,512 @@ +using System; +using System.Collections.Generic; +using PigeonCoopToolkit.Utillities; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace PigeonCoopToolkit.Effects.Trails +{ + public abstract class TrailRenderer_Base : MonoBehaviour + { + public PCTrailRendererData TrailData; + + public bool Emit; + + protected bool _emit; + + protected bool _noDecay; + + private PCTrail _activeTrail; + + private List _fadingTrails; + + protected Transform _t; + + private static Dictionary> _matToTrailList; + + private static List _toClean; + + private static bool _hasRenderer; + + private static int GlobalTrailRendererCount; + + protected virtual void Awake() + { + GlobalTrailRendererCount++; + if (GlobalTrailRendererCount == 1) + { + _matToTrailList = new Dictionary>(); + _toClean = new List(); + } + _fadingTrails = new List(); + _t = transform; + _emit = Emit; + if (_emit) + { + _activeTrail = new PCTrail(GetMaxNumberOfPoints()); + _activeTrail.IsActiveTrail = true; + OnStartEmit(); + } + } + + protected virtual void Start() + { + } + + protected virtual void LateUpdate() + { + if (_hasRenderer) + { + return; + } + _hasRenderer = true; + foreach (KeyValuePair> current in _matToTrailList) + { + CombineInstance[] array = new CombineInstance[current.Value.Count]; + for (int i = 0; i < current.Value.Count; i++) + { + array[i] = new CombineInstance + { + mesh = current.Value[i].Mesh, + subMeshIndex = 0, + transform = Matrix4x4.identity + }; + } + Mesh mesh = new Mesh(); + mesh.CombineMeshes(array, true, false); + _toClean.Add(mesh); + DrawMesh(mesh, current.Key); + current.Value.Clear(); + } + } + + protected virtual void Update() + { + if (_hasRenderer) + { + _hasRenderer = false; + if (_toClean.Count > 0) + { + for (int i = 0; i < _toClean.Count; i++) + { + Mesh mesh = _toClean[i]; + if (mesh != null) + { + if (Application.isEditor) + { + Object.DestroyImmediate(mesh, true); + } + else + { + Object.Destroy(mesh); + } + } + } + } + _toClean.Clear(); + } + if (!_matToTrailList.ContainsKey(TrailData.TrailMaterial)) + { + _matToTrailList.Add(TrailData.TrailMaterial, new List()); + } + if (_activeTrail != null) + { + UpdatePoints(_activeTrail, Time.deltaTime); + UpdateTrail(_activeTrail, Time.deltaTime); + GenerateMesh(_activeTrail); + _matToTrailList[TrailData.TrailMaterial].Add(_activeTrail); + } + for (int j = _fadingTrails.Count - 1; j >= 0; j--) + { + if (_fadingTrails[j] == null || !AnyElement(_fadingTrails[j].Points)) + { + if (_fadingTrails[j] != null) + { + _fadingTrails[j].Dispose(); + } + _fadingTrails.RemoveAt(j); + } + else + { + UpdatePoints(_fadingTrails[j], Time.deltaTime); + UpdateTrail(_fadingTrails[j], Time.deltaTime); + GenerateMesh(_fadingTrails[j]); + _matToTrailList[TrailData.TrailMaterial].Add(_fadingTrails[j]); + } + } + CheckEmitChange(); + } + + protected bool AnyElement(CircularBuffer InPoints) + { + for (int i = 0; i < InPoints.Count; i++) + { + PCTrailPoint pCTrailPoint = InPoints[i]; + if (pCTrailPoint.TimeActive() < TrailData.Lifetime) + { + return true; + } + } + return false; + } + + protected virtual void OnDestroy() + { + GlobalTrailRendererCount--; + if (GlobalTrailRendererCount == 0) + { + if (_toClean != null && _toClean.Count > 0) + { + for (int i = 0; i < _toClean.Count; i++) + { + Mesh mesh = _toClean[i]; + if (mesh != null) + { + if (Application.isEditor) + { + Object.DestroyImmediate(mesh, true); + } + else + { + Object.Destroy(mesh); + } + } + } + } + _toClean = null; + _matToTrailList.Clear(); + _matToTrailList = null; + } + if (_activeTrail != null) + { + _activeTrail.Dispose(); + _activeTrail = null; + } + if (_fadingTrails != null) + { + for (int j = 0; j < _fadingTrails.Count; j++) + { + PCTrail pCTrail = _fadingTrails[j]; + if (pCTrail != null) + { + pCTrail.Dispose(); + } + } + _fadingTrails.Clear(); + } + } + + protected virtual void OnStopEmit() + { + } + + protected virtual void OnStartEmit() + { + } + + protected virtual void OnTranslate(Vector3 t) + { + } + + protected abstract int GetMaxNumberOfPoints(); + + protected virtual void Reset() + { + if (TrailData == null) + { + TrailData = new PCTrailRendererData(); + } + TrailData.Lifetime = 1f; + TrailData.UsingSimpleColor = false; + TrailData.UsingSimpleSize = false; + TrailData.ColorOverLife = new Gradient(); + TrailData.SimpleColorOverLifeStart = Color.white; + TrailData.SimpleColorOverLifeEnd = new Color(1f, 1f, 1f, 0f); + TrailData.SizeOverLife = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 0f)); + TrailData.SimpleSizeOverLifeStart = 1f; + TrailData.SimpleSizeOverLifeEnd = 0f; + } + + protected virtual void InitialiseNewPoint(PCTrailPoint newPoint) + { + } + + protected virtual void UpdateTrail(PCTrail trail, float deltaTime) + { + } + + protected void AddPoint(PCTrailPoint newPoint, Vector3 pos) + { + if (_activeTrail == null) + { + return; + } + newPoint.Position = pos; + newPoint.PointNumber = ((_activeTrail.Points.Count == 0) ? 0 : (_activeTrail.Points[_activeTrail.Points.Count - 1].PointNumber + 1)); + InitialiseNewPoint(newPoint); + newPoint.SetDistanceFromStart((_activeTrail.Points.Count == 0) ? 0f : (_activeTrail.Points[_activeTrail.Points.Count - 1].GetDistanceFromStart() + Vector3.Distance(_activeTrail.Points[_activeTrail.Points.Count - 1].Position, pos))); + if (TrailData.UseForwardOverride) + { + newPoint.Forward = (TrailData.ForwardOverrideRelative ? _t.TransformDirection(TrailData.ForwardOverride.normalized) : TrailData.ForwardOverride.normalized); + } + _activeTrail.Points.Add(newPoint); + } + + private void GenerateMesh(PCTrail trail) + { + trail.Mesh.Clear(false); + Vector3 vector = (Camera.main != null) ? Camera.main.transform.forward : Vector3.forward; + if (TrailData.UseForwardOverride) + { + vector = TrailData.ForwardOverride.normalized; + } + trail.activePointCount = NumberOfActivePoints(trail); + if (trail.activePointCount < 2) + { + return; + } + int num = 0; + for (int i = 0; i < trail.Points.Count; i++) + { + PCTrailPoint pCTrailPoint = trail.Points[i]; + float num2 = pCTrailPoint.TimeActive() / TrailData.Lifetime; + if (pCTrailPoint.TimeActive() <= TrailData.Lifetime) + { + if (TrailData.UseForwardOverride && TrailData.ForwardOverrideRelative) + { + vector = pCTrailPoint.Forward; + } + Vector3 a = Vector3.zero; + a = i < trail.Points.Count - 1 ? Vector3.Cross((trail.Points[i + 1].Position - pCTrailPoint.Position).normalized, vector).normalized : Vector3.Cross((pCTrailPoint.Position - trail.Points[i - 1].Position).normalized, vector).normalized; + Color color = TrailData.StretchColorToFit ? (TrailData.UsingSimpleColor ? Color.Lerp(TrailData.SimpleColorOverLifeStart, TrailData.SimpleColorOverLifeEnd, 1f - num / (float)trail.activePointCount / 2f) : TrailData.ColorOverLife.Evaluate(1f - num / (float)trail.activePointCount / 2f)) : (TrailData.UsingSimpleColor ? Color.Lerp(TrailData.SimpleColorOverLifeStart, TrailData.SimpleColorOverLifeEnd, num2) : TrailData.ColorOverLife.Evaluate(num2)); + float d = TrailData.StretchSizeToFit ? (TrailData.UsingSimpleSize ? Mathf.Lerp(TrailData.SimpleSizeOverLifeStart, TrailData.SimpleSizeOverLifeEnd, 1f - num / (float)trail.activePointCount / 2f) : TrailData.SizeOverLife.Evaluate(1f - num / (float)trail.activePointCount / 2f)) : (TrailData.UsingSimpleSize ? Mathf.Lerp(TrailData.SimpleSizeOverLifeStart, TrailData.SimpleSizeOverLifeEnd, num2) : TrailData.SizeOverLife.Evaluate(num2)); + trail.verticies[num] = pCTrailPoint.Position + a * d; + if (TrailData.MaterialTileLength <= 0f) + { + trail.uvs[num] = new Vector2(num / (float)trail.activePointCount / 2f, 0f); + } + else + { + trail.uvs[num] = new Vector2(pCTrailPoint.GetDistanceFromStart() / TrailData.MaterialTileLength, 0f); + } + trail.normals[num] = vector; + trail.colors[num] = color; + num++; + trail.verticies[num] = pCTrailPoint.Position - a * d; + if (TrailData.MaterialTileLength <= 0f) + { + trail.uvs[num] = new Vector2(num / (float)trail.activePointCount / 2f, 1f); + } + else + { + trail.uvs[num] = new Vector2(pCTrailPoint.GetDistanceFromStart() / TrailData.MaterialTileLength, 1f); + } + trail.normals[num] = vector; + trail.colors[num] = color; + num++; + } + } + Vector2 v = trail.verticies[num - 1]; + for (int j = num; j < trail.verticies.Length; j++) + { + trail.verticies[j] = v; + } + int num3 = 0; + for (int k = 0; k < 2 * (trail.activePointCount - 1); k++) + { + if (k % 2 == 0) + { + trail.indicies[num3] = k; + num3++; + trail.indicies[num3] = k + 1; + num3++; + trail.indicies[num3] = k + 2; + } + else + { + trail.indicies[num3] = k + 2; + num3++; + trail.indicies[num3] = k + 1; + num3++; + trail.indicies[num3] = k; + } + num3++; + } + int num4 = trail.indicies[num3 - 1]; + for (int l = num3; l < trail.indicies.Length; l++) + { + trail.indicies[l] = num4; + } + trail.Mesh.vertices = trail.verticies; + trail.Mesh.SetIndices(trail.indicies, MeshTopology.Triangles, 0); + trail.Mesh.uv = trail.uvs; + trail.Mesh.normals = trail.normals; + trail.Mesh.colors = trail.colors; + } + + private void DrawMesh(Mesh trailMesh, Material trailMaterial) + { + Graphics.DrawMesh(trailMesh, Matrix4x4.identity, trailMaterial, gameObject.layer); + } + + private void UpdatePoints(PCTrail line, float deltaTime) + { + for (int i = 0; i < line.Points.Count; i++) + { + line.Points[i].Update(_noDecay ? 0f : deltaTime); + } + } + + [Obsolete("UpdatePoint is deprecated, you should instead override UpdateTrail and loop through the individual points yourself (See Smoke or Smoke Plume scripts for how to do this).", true)] + protected virtual void UpdatePoint(PCTrailPoint pCTrailPoint, float deltaTime) + { + } + + private void CheckEmitChange() + { + if (_emit != Emit) + { + _emit = Emit; + if (_emit) + { + if (_activeTrail == null || _activeTrail.NumPoints != GetMaxNumberOfPoints()) + { + if (_activeTrail != null) + { + _activeTrail.Dispose(); + } + _activeTrail = new PCTrail(GetMaxNumberOfPoints()); + } + else + { + _activeTrail.Points.Clear(); + } + _activeTrail.IsActiveTrail = true; + OnStartEmit(); + } + else + { + OnStopEmit(); + _activeTrail.IsActiveTrail = false; + _fadingTrails.Add(_activeTrail); + } + } + } + + private int NumberOfActivePoints(PCTrail line) + { + int num = 0; + for (int i = 0; i < line.Points.Count; i++) + { + if (line.Points[i].TimeActive() < TrailData.Lifetime) + { + num++; + } + } + return num; + } + + [ContextMenu("Toggle inspector size input method")] + protected void ToggleSizeInputStyle() + { + TrailData.UsingSimpleSize = !TrailData.UsingSimpleSize; + } + + [ContextMenu("Toggle inspector color input method")] + protected void ToggleColorInputStyle() + { + TrailData.UsingSimpleColor = !TrailData.UsingSimpleColor; + } + + public void LifeDecayEnabled(bool enabled) + { + _noDecay = !enabled; + } + + public void Translate(Vector3 t) + { + if (_activeTrail != null) + { + for (int i = 0; i < _activeTrail.Points.Count; i++) + { + _activeTrail.Points[i].Position += t; + } + } + if (_fadingTrails != null) + { + for (int j = 0; j < _fadingTrails.Count; j++) + { + PCTrail pCTrail = _fadingTrails[j]; + if (pCTrail != null) + { + for (int k = 0; k < pCTrail.Points.Count; k++) + { + pCTrail.Points[k].Position += t; + } + } + } + } + OnTranslate(t); + } + + public void CreateTrail(Vector3 from, Vector3 to, float distanceBetweenPoints) + { + float num = Vector3.Distance(from, to); + Vector3 normalized = (to - from).normalized; + float num2 = 0f; + CircularBuffer circularBuffer = new CircularBuffer(GetMaxNumberOfPoints()); + int num3 = 0; + while (num2 < num) + { + PCTrailPoint pCTrailPoint = new PCTrailPoint(); + pCTrailPoint.PointNumber = num3; + pCTrailPoint.Position = from + normalized * num2; + circularBuffer.Add(pCTrailPoint); + InitialiseNewPoint(pCTrailPoint); + num3++; + if (distanceBetweenPoints <= 0f) + { + break; + } + num2 += distanceBetweenPoints; + } + PCTrailPoint pCTrailPoint2 = new PCTrailPoint(); + pCTrailPoint2.PointNumber = num3; + pCTrailPoint2.Position = to; + circularBuffer.Add(pCTrailPoint2); + InitialiseNewPoint(pCTrailPoint2); + PCTrail pCTrail = new PCTrail(GetMaxNumberOfPoints()); + pCTrail.Points = circularBuffer; + _fadingTrails.Add(pCTrail); + } + + public void ClearSystem(bool emitState) + { + if (_fadingTrails != null) + { + for (int i = 0; i < _fadingTrails.Count; i++) + { + PCTrail pCTrail = _fadingTrails[i]; + if (pCTrail != null && pCTrail != _activeTrail) + { + pCTrail.Dispose(); + } + } + _fadingTrails.Clear(); + } + Emit = emitState; + _emit = !emitState; + CheckEmitChange(); + } + + public int NumSegments() + { + int num = 0; + if (_activeTrail != null && NumberOfActivePoints(_activeTrail) != 0) + { + num++; + } + return num + _fadingTrails.Count; + } + } +} diff --git a/Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs.meta b/Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs.meta new file mode 100644 index 0000000..6389dfd --- /dev/null +++ b/Assets/TrailEffect/Effects/Trails/TrailRenderer_Base.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 21f59b203fc36464997343d7fbb43d8f +timeCreated: 1510298121 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Generic.meta b/Assets/TrailEffect/Generic.meta new file mode 100644 index 0000000..476b0ed --- /dev/null +++ b/Assets/TrailEffect/Generic.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 0a9b95943ee423546af04cdf2ca77dcb +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Generic/Editor.meta b/Assets/TrailEffect/Generic/Editor.meta new file mode 100644 index 0000000..cbaaede --- /dev/null +++ b/Assets/TrailEffect/Generic/Editor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 4bb7bc1d04cd01a44b699141de29a4f4 +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Generic/Editor/IntroDialogue.cs b/Assets/TrailEffect/Generic/Editor/IntroDialogue.cs new file mode 100644 index 0000000..36d94eb --- /dev/null +++ b/Assets/TrailEffect/Generic/Editor/IntroDialogue.cs @@ -0,0 +1,81 @@ +using UnityEditor; +using UnityEngine; + +namespace PigeonCoopToolkit.Generic.Editor +{ + public class IntroDialogue : EditorWindow + { + public VersionInformation versionInformation; + public Texture2D banner; + public string UserGuidePath; + + + void OnGUI() + { + if(banner == null) + { + return; + } + + + GUI.DrawTexture(new Rect(0, 0, banner.width, banner.height), banner); + GUILayout.Space(banner.height - 18); + if (versionInformation != null) GUILayout.Label(versionInformation.ToString()); + GUIStyle lessPaddingNotif = new GUIStyle("NotificationText"); + lessPaddingNotif.padding = new RectOffset(10,10,10,10); + lessPaddingNotif.margin = new RectOffset(10, 10, 10, 10); + lessPaddingNotif.stretchWidth = true; + GUILayout.Label("Thanks for your purchase! ♥", lessPaddingNotif); + + GUILayout.BeginHorizontal(); + GUILayout.Space(16); + GUILayout.BeginVertical(); + GUILayout.Label("We hope you enjoy this tool. Feel free to contact us at our twitter or email - send us feature requests, get some help from us, or just say hi!", "WordWrapLabel"); + GUILayout.Label("Don't forget to rate or review "+versionInformation.Name+" on the asset store once you've had a chance to evaluate it", "WordWrapLabel"); + GUILayout.EndVertical(); + GUILayout.Space(16); + GUILayout.EndHorizontal(); + + + GUILayout.FlexibleSpace(); + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + + GUILayout.BeginVertical(); + if (!string.IsNullOrEmpty(UserGuidePath)) + { + if (GUILayout.Button("Need help? Read the guide!","LargeButton")) + { + Application.OpenURL(UserGuidePath); + }; + + } + GUILayout.Space(5); + if (GUILayout.Button("Want to say hello? @PigeonCoopAU", "LargeButton")) + { + Application.OpenURL("http://www.twitter.com/PigeonCoopAU"); + }; + + GUILayout.EndVertical(); + GUILayout.FlexibleSpace(); + + GUILayout.EndHorizontal(); + + GUILayout.FlexibleSpace(); + GUILayout.Label("© 2014 Pigeon Coop ", EditorStyles.miniLabel); + + } + + public void Init(Texture2D _banner, VersionInformation _versionInformation, string userGuidePath) + { + banner = _banner; + UserGuidePath = userGuidePath; + + if (System.IO.File.Exists(FileUtil.GetProjectRelativePath(userGuidePath)) == false) + UserGuidePath = null; + + versionInformation = _versionInformation; + minSize = maxSize = new Vector2(banner.width, 500); + } + } +} \ No newline at end of file diff --git a/Assets/TrailEffect/Generic/Editor/IntroDialogue.cs.meta b/Assets/TrailEffect/Generic/Editor/IntroDialogue.cs.meta new file mode 100644 index 0000000..8a04d59 --- /dev/null +++ b/Assets/TrailEffect/Generic/Editor/IntroDialogue.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 026003e24f7b7ce43b28fc3c8a4a40bf +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Generic/Resources.meta b/Assets/TrailEffect/Generic/Resources.meta new file mode 100644 index 0000000..458f583 --- /dev/null +++ b/Assets/TrailEffect/Generic/Resources.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: f96a53c06e3e24b4cae13070f3b8a5cd +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Generic/Resources/PCTK.meta b/Assets/TrailEffect/Generic/Resources/PCTK.meta new file mode 100644 index 0000000..208e617 --- /dev/null +++ b/Assets/TrailEffect/Generic/Resources/PCTK.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: ca4b996a254788e47a48279672b9f8fc +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Generic/Resources/PCTK/Generic.meta b/Assets/TrailEffect/Generic/Resources/PCTK/Generic.meta new file mode 100644 index 0000000..43dc26c --- /dev/null +++ b/Assets/TrailEffect/Generic/Resources/PCTK/Generic.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: c3eef40730cf0864d97e8e04a0ee6f8e +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Generic/VersionInformation.cs b/Assets/TrailEffect/Generic/VersionInformation.cs new file mode 100644 index 0000000..96d2f9c --- /dev/null +++ b/Assets/TrailEffect/Generic/VersionInformation.cs @@ -0,0 +1,44 @@ +using UnityEngine; + +namespace PigeonCoopToolkit.Generic +{ + [System.Serializable] + public class VersionInformation + { + public string Name; + public int Major = 1; + public int Minor = 0; + public int Patch = 0; + + public VersionInformation(string name, int major, int minor, int patch) + { + Name = name; + Major = major; + Minor = minor; + Patch = patch; + } + + public override string ToString() + { + return string.Format("{0} {1}.{2}.{3}", Name, Major, Minor, Patch); + } + + public bool Match(VersionInformation other, bool looseMatch) + { + if(looseMatch) + { + return other.Name == Name && + other.Major == Major && + other.Minor == Minor; + } + else + { + return other.Name == Name && + other.Major == Major && + other.Minor == Minor && + other.Patch == Patch; + } + } + + } +} diff --git a/Assets/TrailEffect/Generic/VersionInformation.cs.meta b/Assets/TrailEffect/Generic/VersionInformation.cs.meta new file mode 100644 index 0000000..c5b4e1a --- /dev/null +++ b/Assets/TrailEffect/Generic/VersionInformation.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1d58a7e753bea0e4c84779d092563363 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Materials.meta b/Assets/TrailEffect/Materials.meta new file mode 100644 index 0000000..8f0a3ec --- /dev/null +++ b/Assets/TrailEffect/Materials.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ed403bda32d6d8b4abc0e3a2de4b8fa1 +folderAsset: yes +timeCreated: 1497081290 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Materials/Arrow.mat b/Assets/TrailEffect/Materials/Arrow.mat new file mode 100644 index 0000000..b5ebb44 --- /dev/null +++ b/Assets/TrailEffect/Materials/Arrow.mat @@ -0,0 +1,40 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: Arrow + m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _DecalTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 9e6a712ea43474b4ca7d6dc2984f9e2d, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/TrailEffect/Materials/Arrow.mat.meta b/Assets/TrailEffect/Materials/Arrow.mat.meta new file mode 100644 index 0000000..ee7ab98 --- /dev/null +++ b/Assets/TrailEffect/Materials/Arrow.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: bf90f05c17802054f98f9b5f331d8953 +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/BarrelSmoke.mat b/Assets/TrailEffect/Materials/BarrelSmoke.mat new file mode 100644 index 0000000..4641b35 --- /dev/null +++ b/Assets/TrailEffect/Materials/BarrelSmoke.mat @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: BarrelSmoke + m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: 984639d35625032479433f0f906a8bda, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 98450d1e53061f840886062fc42513fa, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _Cutoff + second: 0.5589286 + - first: + name: _InvFade + second: 0.01 + - first: + name: _Shininess + second: 0.70927906 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 0.02745098} + - first: + name: _EmisColor + second: {r: 0.2, g: 0.2, b: 0.2, a: 0} + - first: + name: _SpecColor + second: {r: 0.1397059, g: 0.1397059, b: 0.1397059, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 1, b: 1, a: 0.19607843} diff --git a/Assets/TrailEffect/Materials/BarrelSmoke.mat.meta b/Assets/TrailEffect/Materials/BarrelSmoke.mat.meta new file mode 100644 index 0000000..df64962 --- /dev/null +++ b/Assets/TrailEffect/Materials/BarrelSmoke.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 2c45238b0e8e5b443a693d7c92c89d3e +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/FlameSwordTrail.mat b/Assets/TrailEffect/Materials/FlameSwordTrail.mat new file mode 100644 index 0000000..db50afd --- /dev/null +++ b/Assets/TrailEffect/Materials/FlameSwordTrail.mat @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: FlameSwordTrail + m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: 984639d35625032479433f0f906a8bda, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 98450d1e53061f840886062fc42513fa, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _Cutoff + second: 0.4464286 + - first: + name: _InvFade + second: 0.3592857 + - first: + name: _Shininess + second: 0.70927906 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _EmisColor + second: {r: 0.2, g: 0.2, b: 0.2, a: 0} + - first: + name: _SpecColor + second: {r: 0.1397059, g: 0.1397059, b: 0.1397059, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 0.88965523, b: 0, a: 1} diff --git a/Assets/TrailEffect/Materials/FlameSwordTrail.mat.meta b/Assets/TrailEffect/Materials/FlameSwordTrail.mat.meta new file mode 100644 index 0000000..193b9a5 --- /dev/null +++ b/Assets/TrailEffect/Materials/FlameSwordTrail.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: a6c0d0c41df93a243b0e594e935d9a86 +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat b/Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat new file mode 100644 index 0000000..ada4e75 --- /dev/null +++ b/Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: LowPolyTankTextureTreadDecal + m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: ab6d9a235b23c874885a173a6a2aa027, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _TintColor + second: {r: 0.3455882, g: 0.22165315, b: 0, a: 0.5019608} diff --git a/Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat.meta b/Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat.meta new file mode 100644 index 0000000..4e8c6d0 --- /dev/null +++ b/Assets/TrailEffect/Materials/LowPolyTankTextureTreadDecal.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 0e0449aa4e0e216479ba4ebbe28e8288 +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/MuzzleFlash.mat b/Assets/TrailEffect/Materials/MuzzleFlash.mat new file mode 100644 index 0000000..f94daef --- /dev/null +++ b/Assets/TrailEffect/Materials/MuzzleFlash.mat @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: MuzzleFlash + m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: 984639d35625032479433f0f906a8bda, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 98450d1e53061f840886062fc42513fa, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _Cutoff + second: 0.4464286 + - first: + name: _InvFade + second: 1 + - first: + name: _Shininess + second: 0.70927906 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _EmisColor + second: {r: 0.2, g: 0.2, b: 0.2, a: 0} + - first: + name: _SpecColor + second: {r: 0.1397059, g: 0.1397059, b: 0.1397059, a: 1} + - first: + name: _TintColor + second: {r: 0.69411767, g: 0.69411767, b: 0.69411767, a: 0.19607843} diff --git a/Assets/TrailEffect/Materials/MuzzleFlash.mat.meta b/Assets/TrailEffect/Materials/MuzzleFlash.mat.meta new file mode 100644 index 0000000..6030f44 --- /dev/null +++ b/Assets/TrailEffect/Materials/MuzzleFlash.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 43839268c81ec7340b2eb815c164e0dd +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/SelectionTrail.mat b/Assets/TrailEffect/Materials/SelectionTrail.mat new file mode 100644 index 0000000..d4b1e26 --- /dev/null +++ b/Assets/TrailEffect/Materials/SelectionTrail.mat @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SelectionTrail + m_Shader: {fileID: 4800000, guid: c105fca0e8365434ab3e97e8a6979893, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 62418b70010db0749956023a9435a814, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: PixelSnap + second: 0 + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 0.8095238, g: 1, b: 0, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/TrailEffect/Materials/SelectionTrail.mat.meta b/Assets/TrailEffect/Materials/SelectionTrail.mat.meta new file mode 100644 index 0000000..5058e81 --- /dev/null +++ b/Assets/TrailEffect/Materials/SelectionTrail.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: ee25fb26e9e357d48893fa69862a63d2 +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/SwordSwingMat.mat b/Assets/TrailEffect/Materials/SwordSwingMat.mat new file mode 100644 index 0000000..911de14 --- /dev/null +++ b/Assets/TrailEffect/Materials/SwordSwingMat.mat @@ -0,0 +1,40 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SwordSwingMat + m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _DecalTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 19bac775940f2024a80fd4f854a89757, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/TrailEffect/Materials/SwordSwingMat.mat.meta b/Assets/TrailEffect/Materials/SwordSwingMat.mat.meta new file mode 100644 index 0000000..7ad1493 --- /dev/null +++ b/Assets/TrailEffect/Materials/SwordSwingMat.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 75a9595d302878140b92c9b78b8d8a54 +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/SwordSwingRoughMat.mat b/Assets/TrailEffect/Materials/SwordSwingRoughMat.mat new file mode 100644 index 0000000..3acf9f9 --- /dev/null +++ b/Assets/TrailEffect/Materials/SwordSwingRoughMat.mat @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: SwordSwingRoughMat + m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 0e3f7f3b6dce3a94a86111da4203b740, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/TrailEffect/Materials/SwordSwingRoughMat.mat.meta b/Assets/TrailEffect/Materials/SwordSwingRoughMat.mat.meta new file mode 100644 index 0000000..deeb190 --- /dev/null +++ b/Assets/TrailEffect/Materials/SwordSwingRoughMat.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: ba822564932e653439da54554926872f +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/TankShellTrail.mat b/Assets/TrailEffect/Materials/TankShellTrail.mat new file mode 100644 index 0000000..55a1441 --- /dev/null +++ b/Assets/TrailEffect/Materials/TankShellTrail.mat @@ -0,0 +1,37 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: TankShellTrail + m_Shader: {fileID: 4800000, guid: c105fca0e8365434ab3e97e8a6979893, type: 3} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 62418b70010db0749956023a9435a814, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: PixelSnap + second: 0 + - first: + name: _InvFade + second: 1 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 0.8482759, b: 0, a: 1} + - first: + name: _TintColor + second: {r: 1, g: 1, b: 1, a: 1} diff --git a/Assets/TrailEffect/Materials/TankShellTrail.mat.meta b/Assets/TrailEffect/Materials/TankShellTrail.mat.meta new file mode 100644 index 0000000..eacdd63 --- /dev/null +++ b/Assets/TrailEffect/Materials/TankShellTrail.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 74ac504b5aa2e7045830c0f69e8d297e +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/TankSmoke.mat b/Assets/TrailEffect/Materials/TankSmoke.mat new file mode 100644 index 0000000..83afe45 --- /dev/null +++ b/Assets/TrailEffect/Materials/TankSmoke.mat @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: TankSmoke + m_Shader: {fileID: 203, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _BumpMap + second: + m_Texture: {fileID: 2800000, guid: 984639d35625032479433f0f906a8bda, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - first: + name: _MainTex + second: + m_Texture: {fileID: 2800000, guid: 98450d1e53061f840886062fc42513fa, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - first: + name: _Cutoff + second: 0.4464286 + - first: + name: _InvFade + second: 1 + - first: + name: _Shininess + second: 0.70927906 + m_Colors: + - first: + name: _Color + second: {r: 1, g: 1, b: 1, a: 1} + - first: + name: _EmisColor + second: {r: 0.2, g: 0.2, b: 0.2, a: 0} + - first: + name: _SpecColor + second: {r: 0.1397059, g: 0.1397059, b: 0.1397059, a: 1} + - first: + name: _TintColor + second: {r: 0.69411767, g: 0.69411767, b: 0.69411767, a: 0.11764706} diff --git a/Assets/TrailEffect/Materials/TankSmoke.mat.meta b/Assets/TrailEffect/Materials/TankSmoke.mat.meta new file mode 100644 index 0000000..8eeea9a --- /dev/null +++ b/Assets/TrailEffect/Materials/TankSmoke.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 31435463954d86b4d837cc81741fbf2d +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Materials/UsedShell.mat b/Assets/TrailEffect/Materials/UsedShell.mat new file mode 100644 index 0000000..8c107aa --- /dev/null +++ b/Assets/TrailEffect/Materials/UsedShell.mat @@ -0,0 +1,28 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_Name: UsedShell + m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_CustomRenderQueue: -1 + stringTagMap: {} + m_SavedProperties: + serializedVersion: 2 + m_TexEnvs: + - first: + name: _MainTex + second: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: [] + m_Colors: + - first: + name: _Color + second: {r: 0.33088237, g: 0.33088237, b: 0.33088237, a: 1} diff --git a/Assets/TrailEffect/Materials/UsedShell.mat.meta b/Assets/TrailEffect/Materials/UsedShell.mat.meta new file mode 100644 index 0000000..2ff92a0 --- /dev/null +++ b/Assets/TrailEffect/Materials/UsedShell.mat.meta @@ -0,0 +1,4 @@ +fileFormatVersion: 2 +guid: 28b26d01baf691f41ae86e9f14169cc5 +NativeFormatImporter: + userData: diff --git a/Assets/TrailEffect/Textures.meta b/Assets/TrailEffect/Textures.meta new file mode 100644 index 0000000..7be4867 --- /dev/null +++ b/Assets/TrailEffect/Textures.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 14d3150ca4de43f4b96ec7b2073cd409 +folderAsset: yes +timeCreated: 1497081290 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TrailEffect/Textures/Arrow 1.png b/Assets/TrailEffect/Textures/Arrow 1.png new file mode 100644 index 0000000000000000000000000000000000000000..e5b055b62ad436f89179ca75c1ecb171557aede8 GIT binary patch literal 3685 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 E0qsc4vH$=8 literal 0 HcmV?d00001 diff --git a/Assets/TrailEffect/Textures/Arrow.png b/Assets/TrailEffect/Textures/Arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..7443856f36d1a57b1de811f486c004488df1f2f7 GIT binary patch literal 3670 zcmcgv3s4hh9uGc_9zJF)zQ*yfx1Lpj%|4QlWF?hHKtKbCQSs~*H@jbw)g&8tHzA-@ z4mlswqSxBmdVm8}JZ;N49fY0_usd_%nj`wX60(PV@y_?G< z`}lvq@BjLK|Nr-8V_wdj5it{DR4UbotW0x0yq77z=LW&+yqEq}4R1g9W-gIbs$sFp zFG}_M>hUU7jLcgLz3W{`l}<&o%s2@UF{;j<#fQ6vbF zSD4Tg#UN5($wSfv5g>XsiLnGhAbO)3a13SB*b@+nph%pAUoA#bw1%Ly6cYZR(45HG z>3nlW*cf~>p-x%$(l}mJRHQD_s0Go1lSZQvCn%hvFo?jUVvo!OFpo5~TZ0)$tjK$1 zUhp7_M#d)iWD^Qq4aMO0M$~$waGqes@Brh*Nj0Iw6a;c?1n2dMuAp&_#eoaBfk&1g zmW*Iwnk<$G{F!Rq?g(0v)BVt+aBR;+OV(m9!1IA5_(T?@`=Q0D-Hu6eKIlo!0H#BD zWU|*O$b#e)`ba`#_^DLLyuA;D%E(ht5a9cODkBl7mrfG_BMYKc5M15l$?NtFNn4PJ z%vj8OIH5?Isl*+|12ZE76G{<~L4*dQNGnOul%A$^@gzwTL}68jL>6L zqLtLqIwP&q#1pz6u)y*5;(nnVOWOs}&A@fz-HZd^UXLSa&0?XmJd(_KSde8lq0m(| z&vUdvZ?F?202s-z6h>;aM$ACkA@3QTjLKPvMj@KU80wz(O67#h`V7 zNCaBOi0N6D#Oy$8z!;VR7|>}s1IHK{0H|(lxgrlsoN@Kms(8ggjpkHCx;a%t8uY0| zx`reTW@BoGj!e}WQnjQu5$fo%nI^ad(IRj#-_X+@c~)9lo+#LP7aWlC=cFQ8>1m0i zF)(vp70dxjT!c(@MGTZL0} z(9s33zd?tft)MKA4**wznTKhWLQYVI-a|`%Fr+j)rH1KDUV^MF4tJvkU}gBp#UsJ8 zr5QF90ITp9aA;V}KZ67PXFH^_$O&MYeuUH^m?YTcB1Qx$4w&2iY6kDiZ;A2u<8@kp z9O>I@4Ml5-?o#{-UWb#(IvI}xz}*Q)e|j7w1vCaDu)~_+^q5_*)nW$5PGEo|f!3(A zvswUo{d6pSc8USTLTS`w@3s}1G>~9e!Q%&FFFJV{k%2ob5G5087X>%Mc)c#34OSHH z_i*8TD^it+EFe97sn4WwK;(NZe{U-h7m)vPIE0EH|6yMUy_-Xs z%uv=QxFOTe>Hq`fAl#v8*z+U1z`*-;$hPp`^n8Ua!GL?6oVrEuIHo*C4ubF{a+Cxf zSfL_3DDKeOud7spH)NSptbytqU$xAgnlk=q*TI0Z@%b;BDw_}d2nHPzK`who<> zm$!?bJbChaId$6#XVp52iuEkDWaFtA|Ga$p*3Fxrw(e-2 zc=W@B_dmZMxqlG}p9UD*s^T;5YIU#%i|B z>j38~w%Er1<>ABP4j?C&Z{51}(a7xd9nYP-)A{7MMcTZ1vqqySANuaekJ^_XKe3~x zrNz`WXnxeog@yI&PUSTHs=*r9sgslQ>6)Cxsv8Gi8=0A1m*-5ZDt&un%v8qhF>6_~}Z?0>})(-1jl@c8tos#jHDLy`aRO`4Q zua^~C?v@_Dbu4QBkS8AJw^L4O+*_A997lb>ZlC$H`M(?ar$dLVlO%7~ux)$Q7mme_ z+BmE1=<#Vek7r%nzkmOOrQRXw`wkyovu4d+`bh0JOGXvWuXuer`iPC5IAzNFC+aIt z4)soS$g(xWqQsu*Z28XY**$0H`_62lwWZNXrc+D+fRiT1`nCW-j+YR? z06U)C?v{B0z;yPOo}TqB6bb<2#N3QvyUWu&@zhq;R_k=Oq(?*EH*IN*PqrGT$(~bS zWHW6~1)?hYc4&Q@v=RnIsd;RXURteaQY^%#c9j;cKXwPr#h+nvod}<63EiON%nAL7 z^v-Xkez>uLnP>v3N6~a|%$*pqCkmaoJ}q@6q~LEL=^-aJ0n`V~qwDH)dG-xyvS=cv zl6|r`_jy~JScHEbo*UIl?f`%CACa9!6@YbS^3wMHv>TkaPfgSDsW{21FY}eM#h|?D zpr|uW(cxjhwzO-+_bg9V^&Q2Si}3z{!3EFFFSC-LQ`9-ylGBiI-X(^8vSOPADmu_4 zPP^OxOD#OYQUyq*&&n0XG#;` z5^k5{QXX>RKT)X`OZctI;781z|+qVnSH_lhi&bpaF^1aW>EpHs;vqb4#iJ;oHec1TtYRJw*we&y*Jr7ksudovR zx4nZ4=$|JR^W*o0=zj;D=3zfN)0QCj$Uwip#9Y`sqrtV8Gl4EkH%@y$KYO3G^LOzy zIU{jqpM5C9iRQV;DecJ9KL_yiu;XmY&8Gf%X21* zfHKloY~-*R{FZ&>LZd7U478yu+WgB<&UV^Y?d*+!bskEiBb7jV2dOZR<4T3-3-fYe z8w&Uy;fP4dGFVUnyK=M&nlJD^YF=55UiN-Jl6DqiE6lzRHkwi)7;XYNj+UGL{2hJEA4gVf*BYnSerj$eka5oyYMWd(4kPJ zsKSQcI=Af7nEja4ZKgeT3q$W`l;Oc;5Gaj+=i+4z9Sd@X1efcU*>}|rxM9(SsAL5K zUzE9k1a}=x9lVZzl%O69?@qp2QtR{rF(I&;bh7Ji%{3o|S4`n-;T+*~8U#$V*g_!s zmD&}zi3&%&cjbzrYoz4C&&waxP)<^~|LcWL;XEI||jIr*y zt1^Y@LxyT*jbm*@ToNI4axi+PS^Rtad64 z(Z6H7RnFnjXPiiUYvc0Vt|-v%Yure^qW!d?x}CaSXx&}>Hr+o)T+&?$3wobylB5o$ zZb+f*Vk)dWFO$cD#tc`SSJY1GDV5L-+1`3y?|(D8{w#M=Qm$#eX`X4yyF1)x1q=Cy zq03))6%Vc+1RZGD%h+4lx2;HwtBjwos2*P|3oY9kHyxW9Hyry|t~7=j8yzE+2ba%{ zYTwGd732No_P1fR%B?^aUqZjY`qOmv_@&v2m!SigPbWquwnyKMRE!{s z_Uv-1)(UegTJ;WNz8ACD_gEMe)afl152E6jIv=JDmR;XfC<(j}^eafbX|E}|Nhz#5 z%qA>0Y%T1^F5`jpuQR^{4_Xf{!w@hL7#)lVBc0relkVi|bdUQLSDliaaxGbfF9@!w z=%Bh$p>xQxg|%P`9{OXoYoow{6o>sCkyH+}tc{XX2p^u%4`ym|TN zC~BvYm?bm$s{8wl+qT;rxpL_q72|iquZQ#=6+D`ETj<*Bj<(6)(a}ZGy@iykBg5?q z!?hDzFnl)?%GWD5SXU!dop=wixH~c3;ruOP>L)L6iCMN8zP~86duM;=)KUt0g?!g- z)&05O36egk)z3EAJ(v(4eF$a6u;v*(?1?EYzfrNIL%rcK;UQYhQa$N&_ST$Ua;KUA1VdXus%&ewMz;v#=uWBF<+yMOS)4dLH!{qlniWyFHRd6FA=n^`Jf% zea=}Zm4UZGWGmOZ=(05yx<%LZVFKhI-*s*x>F6 z_IZO@X`|1&>^f&2y+6Hw`o=rCC95-JiN}(fruQs9=3UHM$g@q`wrl6HW6mo*D4lrT zX31>vKL7h!O^H@b=##X}J9ftGC5(rP4N5zT@pS`rNp;2jPoJ#0sfaUiT=3MJ#=mUt zQl6%cVc+V%^ia(HoN@W#j)W@WhjHHBJb8a4d3xKTUve9>^V;LSONaZgYk_OcD`epF zrFRGRLlw^}!yH$uWnDDey8S8l8)6!6c}Gdr%Sy{dkY&BxtYD^I!C9+kZ@Pe0&8nlV0yxGf?P5br^8? zG_m@AmLw?UC`*+SdVl(5YXCjUsE_bO#L47Bz%q8OEVX^+qAocodXs3Fv2ZtT1J(l-m^NIj|NdFkiy{*50(qnZu@ zZvTW#GrmcD#+h%qnE&+B3J?*6Um3%Wd@J+k04{h<&7CJ57r7l?0?({Nvh=cz_4Bpp5;b!@H9Yvw_( zjr1O+eOk4d^#5qwDAL;3{BzmifVe~o@T1N;2k>G@U-Cv;lMb_g@JA~Ds&!ux*1WW$ ziP%JTL~EdCYbCWj|LjJ#EQ|cS+7&aXza#eEs7C@LDW~PJA97?e@i42jOY8g}x5I%i z)4{Jpjuhp&H7@*i+dUes&bdGW?Uph(KK>`7m1q?v|0%+3%2GGv_7yR|p z4yOVSkE5%?|A&vy30pMyf27^3gdM;AoQZx@^l_*!0t`~Alvf5t8HIb&larG?gw+7w z!b!)8)dt)tQg%F{RVt>oGIYHWFUm*CULv$+Uc?VJ2K0DvbuKD=pS?rf7ERp{Dhqux z<;q7=g~al9&;r^y`3xqMLVD#`jj(HY@6H{u2E@G!jyscJYV98VFR00ePpMm_I)yxO zH!7-{6*nfK8RspmolVlj!l3^{W={s1%?2^o4rzC+0Uj3+72@S@=wT- z{#P~`0PO>9cHnYrUl~ZtqiI2I8fbr`3uq4~_iNW9FbElbQE z&?LO{sBSh{I<>)b`}$x7%iouuuex$l*V~#vAPB@rUvIF)zzS$TAH3(h!t6k-WX5W7 z+dxWPYi<)K#)H6NeE5KbgyofaE=3>X1EexAGo zpO1-*4E!Rd7f=eV$qZy#tRjGrW?_6)u7QO7K&}`FmqQGE2&bQ4A3h!6wSEoSzToKH za9RQ6<>%*Q`>d@8;*E%b<>q%%W%5(_u*iDf$Y02 z5On*F62?Av@r41ou@TJ|Z5_!YfSdmHAEG$;^aHddRPTub+|RHVsXRcqSQGkh>QTzv zvx@#Hz~jY&RsR!^-5F+T!;Pz#Y-q96)KSCLZMn%kag2x}o>A4Ifg-r^1j97sdN_&FSj~2`3XO;e z)UHD_UicXfv^87kk3&khNE3o*KGyl)LNE^pzqUU@sv!lmS+rUR5XgxDLl(u`Y-|D$ zY%iGdBUONM2s$`;DT1*avbnok%!GR|2CQjv_>LuYAJmBGfT^ieZlHqL-I&Cz8wf9> zQC7cCfHMDRX0VL@%miva(ShA2bvmGOf~H*p3PDEWK;}fxTr($(0bDK6&^cC^7+9`v zW@{3GAU~xwl@l?L`Ksp+@6xu@@ER5#lkniZFdIK8EiIjq4-RNxB94aBr`pXw^1e`7 zwKod(b+%-jE-(|F$t^8*;$^*$SRIYN0&}){^1W}r(`L>UYU90)K;tN9%e|y$dh0W1 zlTuQ$`-NZ~hUP3lyr!eqUE??~@sKqJz@I(eaM_&eOI7YQnwrpn$5;8x)mDUD4zDfv zB5?VTeFNc~gxQA6TyTEneKyA`()A z)X-l(?|<`!R^;GgCdCEm{I-O9E?v%a8?fALvw zrVo241@LAr3vKutKlK!J%;Xh|7W^FyptZi*Vy1-6Mkgpo$OgwpEreiP)$#N^R>rSV zUQ;IhnwZevOd1>&A(c+yToYZ$r#EN%Pp`&`{d{T~kxv3NRXHISFXFu1r~&I8km0B6xG_6nAn`*_0BQI$md-F6 zqk%O67yi2CWh-4!sRy6%*1<(7X{4%c*o0Bf&x1eqK}WA;GM|g8+DLmlhg7Kz43Dq* zo)d4B#$j3UZvt3oD6Y7A;)S!+)kdoH*z|Icmcx|sxcMrt;MmdvEZOIqip7qcge5G+ zWR4lQlAQq_!2BtlQ%$TL z_Go;!;K~9l!3L%OE2W(h>w8hHw;49{X~boZ2YvIh*P*(}$O4 z>5S_*xT+L}Oj!insw!GwYWPl>(L1KvSAX9)Z&_~fK4<6zNL1U(9=XCUs6+5MMW9uE z7EKhMxGi=DG6boyw0&POVlu2k(QT+~Uz{-V{aAy~xo8SALZzr`3IsXDgYqO13YvZm zm5d-RCzRokMIqP z-zm;Knc;OOJfYCn@F*YqKE4G!7kEHloFt@ST2?s8yw$QraV&E|jTiIAFe$) zhq?vaLf^tTohtj1{!6lbRkPXq2Xjn2i6n!5O%9%-9|=RrLt&w~a;f1loNLd0Kg!rz z$v=$eA9#Yc@V)12>Py*9-vwJCKS(AUJi?3|I$<@!$RY@oQcKx+DU+cMv05tk?FHXt zPHM>Lw(ABdbHPsH9}f7IBidh?Y0In08!&PAa6i&==91!z;$rt=-@8}L@sp#Q?e$lU zr(}Ne=6WkC-aMu3tM_^zmEAYH58=g7nefl>KEH4ED5xslRO0dRW2^Uhjb?9x)ShV_ z*1&AOY9-VUJhG^K{Py|d?N?K+Vow$|WFO0_2DkVn{lopENhL5Czoz=@Q6ldpuM4l^ z{yYGINsXKg5>Xkaev|p4d8@IVU7b`g?!6{+tx-n{zJxpq zc^R@7a&`>85V+>LX1?gYFvfd;$Bu`KSC7|5a`;N%Gu3D7SJ$r^Q<760lBMVZ=oQ3F z#7RZQrM)G4JXEBfNt-)Q+4+r8Iert<7ys!MvPdk|BCRW0C(0-mH^w}QyYXo(PH>Xu zA&p8BUJ|1oZ2EQnXHTb8iz&evK_bCV0;T5kW`mYqEq~iCT)ljXy??rf5501rbTxLJ zc08)9&ljBk_~mrT>YvqWN8RR&iEwWh@1eFIj)Bu9?yL^IeLeFxF)?prhTn|YPkl#; zes7*T#7p`@=;-BK9H=4}EL;EL!N&32VxReL*upt2ZIy0;Zqmrx;4eqmBZkeCj=vp# zRy)>}-o$NcZQb5Rf!2Ykp)r>@WZ`5bny-gqt7}|pH8$=jz~6%HUnQqPa-Dw-kkL(f6jRs&YB7(BWi?3(%Dl! zBLCit=(PJ9orBxR(akZ!aiEs3rd=NLmijGadEr~zp`f9xAuY#x2h%S$iPQ0v0|7&h zzu*2YT&t$N5LoW;mG4u0BlGKmQ=XV?hEZxmf-u~`(z$`6W%o7>fp(~r=asff2Bk|f33tQWk{R z%ASWr`aeof`4o7%6>xGh@}51`qNsviiXp|1#Nt{;TM}C;Mv8LxtfaUJVUkX&i%B0o z4N5Fd%peBTKG=vA{LV3ceZ(XE;7qH;uSCShu4D0^{>Z(5;YYnTQ5JpH-!025n?Bk- zuiX50@no{LvM$7Qr%}j4q34UwSQIiA>E;p1+bSd=9M&P^Y;BNX^1YzE`6Ob;GKo4- zeNbAe-Sgd#_$A&2nRd7Rs#<+k-5_pS-FjVqomHO=?;dRSm}$0c_)=!8Q`6`h&k2)J zlV5W?KbG5=c};~Tgjs*EeCYPachvlvnk$#P+hu5P`lv0bN%w=U1-;dxwUZ$d`8Pa3 z=R_;TR6n%dd9P||{!{R$#@)k(X_M+FrWR-3jdllPA-xylcyC`NhUbOLUb0AONS{WI zU37M6zpZKA{v7cuVmm4xCwwe*Y)r5~(5c?Ht|H){U4P%mYEb0#&o7>JKGkixEZ{h< zIF`sl?B2;|<+#warqtGO7p%1xKJsk^ffOw2WPC) z3MT$me}WdF{R!oir4Khsixjg1{%&utPdj$&h8z?nDEQY4cllsECl`-4!zPNi&vuo9 zS5B^)iNlBu=-ls2-4qHpS%$_#wZY=pk z*B~#srmj!2x5fazU)_>U) z6#ptbz}WT0$T==I-&1nBJ&x$wVn4SZj2%}y;{2gG#1no`Sjh$(bfrD_I=^~QiT~E> za&&z$us7&ROoUoa^2X};YPzw|_FeD7?bN>0!SjXVYg770XPexvN0I($!5y#LPkDiq z;vEOg2mDHT5nJbU$A|mX$p)nnIA^g(mxuWDDRZ@h$4**24{~plP&xk7kU<0(( zlphBz?S)%TFl&BC7JGt0U`QsN3XC-xN9CE!Fc<`*wZcT6<5ST3rlb>m(OxJ2ZKu^Q zT9mNr;}yPRukh#Z{@;?4Me)!;?YH423UM}dq}J8}hi_T0w_=D?UlGe{2S2rnW>>`n z5z~u3B}b+I|CS$lKRttz3a2UEU_0g`Z!cGe)ak_t&{XUGrI*VQm)Ietp2+LA-s`>o z(1Y%_NG3Irr`{bhCO8jYr-ko2Zra@bX1xvCk}JJAt`0x_xp#_={998!-c5$N-Bh|= zr0kPB=n@zDmu?SY(oy`EkyfN|yM9k8cw8@T`)2*MK}iOHx{Xu1vcIKIK>zzQaygcX z>b*H>Bw`K2^u5$%4S#-nv3h%Rw&-G@bbWl&t9ZFMVH335JS5b0GH3Z)gP0!D6bnoe z-WY_fQC?~S|Bgy;uWl#+{K?hG+iU+Dxsn)S;3o8J-x?b^H%ku+0>jY1ZEr8;uQ`FV zTeQacf7Smoh`e~sC`Z@OpRNp$0CA|%D&f=#o3O({|5Xs10ujRQ9`@Z~Ho4+a{sh-p z#Bs#3!C;I; z*X#mBgku-d8l80zio%}+sgMwcO#C|goLe2as@r7S4sHUPd>&F-97VPRs;N1Eyxr#A zM`cp3RR|3#mIDuo64b^S6-Ktq!Q$X&;HpA(@ob1|M&!*=X(*bL?j4HNj@9omgd7z7 z?cPNG{$Fv*VUw6@fCbcpZ#KU9`&OB_=-)^OjjZxR;3MdYT~iy#bN=+~w+7{~zeC?o z$}JNS1p+}5TV^ic{2=nSFhE#~RF(s~=M(v9{(?Y?l>TmS0I<{9BeKQzM@+NLKYp{l z3ig)#6+oE&?^hhF;_>z6*};J}P-fcPcoIIL1GfQijU%=2z))g(KM4pN&Dnl3C>-&u z_XN@_dF=sD)4VtYl;X9u0kmcpTpL&&%mIh$V8US_L>h@*8<)t_;SDHI7DtXvUg7k0 z_FoItdVECL#n3ga>C-u80nE9V@uvHiqtb4ihtp>%0SVDeXPNB5*0xZ}bUtYx*ErvD7@;OMydHa3%D?hsfKGfron1OkWLsm}O<7)s2fMxSKDdzv zPBzKNhOM9F4^uADZ|AA)Lni>IOIsl;D+|GuGP`?tyk9hwv z2F}?Q%{uM9Op8=Jjhm2Yu69}S{5D`~^n-G=cF-U3=WOo+!VN}F>cqlzRiwYMMR9Ti z(JQ*6%`||`?fFDx1i=+VA$LK=Ci41(2UhlK(^+Xp(7zDt{;(Rt)@nEIW+!>BoAjD$ zKvo5Pvm4lc3!^7lWCK}!da=i}#hD;W7y;PM&%TBLZ1Qt3peHQ_UW$X!Ex@{$RL7#g z@2E#v%+7o8XWp$7up@hOZt4B(z?csQ>5~q9Y4z&pdoZk2&8rH)Fk1_8qlij97)LUA zyHS>kb5W4!lk7qxe3W*e!&^O=ZhMetEb!j>9(Fb8cgi*A*mVuMy5j(<1;o7KYgs|R z=~b%!qV$xi7tc!JRD3fSG5U(J2?W-PvYh{xJ9=$JDmS;7i!vY~C`X;m&bQ(WADy&0 ztd(XGOWUbJM4S#uu2s??7)3bqS4_-CH7+WABi_z~=O&%qgJP_E@n=_XOK>)Glslv4 zJ14YYd2|2$&Q6Di)j3*_JfmH9;EF-H^k}b*$0qogeFwND67KTV0Dm&U;4E8t8c(%$ zDC=XY@seR6QifH>h(0Pzqn8u20Mo-&q{i+%I1F}*xt-Sr7G$VbiwGcIDJdt13ic?{ z)t2v(J*7C2i3C7I*3VS(DEGjEOAl)kkIjX*xa#v90@jMrkvkG+hfMo2eM$+y`~1z5 zw$Gb%R0}e*acrzn2Cy26_xI3vnAOgJ5$>p&4@<~PERY)Q!p|i#g_yr*WnafthA!0u zbie{d+iov-cG2Mo>X=R%EDJ@2-#N(dDUG*mK_h$#1|>G9#eR3Xzw_-3EAIX;(|PEx zT!d7B;adqBDe~0%(>fYd4lb9W&K14bz|kQm`alPOSZcSlK{~rW%mYeu^db#q>;3}K zGQbfwj+pQK9MXe#UO>P`yD*XgPpP4sb)Pw|Svs4!Datk!TdJKASfLlw3qLt}iwcCo ztJj+uMr7-^`7<01p=f$>l`oG_9q8!$u5Ux*jPEMBGrJh z&63dlQRb!q{5c)4p~3Sa?DM+?#dy2TSS?g}NB zXlls!UrADD-!B_qW zb3%mq)D{VhD9k6);w13tj+gEa)pFGQ$FrXVaL}$fh+;AnSH3+x{&MhDqLS7=$Tj3O zB8ANE)>nFexufNFqDC=92$0hB6$W3eEah?G_jUIK9Xepm;)o1sil-ZAPj&V!O5dvC zu@eDN4@jjfrQTO;%Vy_tfN*&PqAKwS3$oLn!oh^(?VK!FUBylkglKkKo3=Gh*ySY+ z5paeV&M0i#)74AbzS-_9(+dku-R^sUX@i^*L^x;)MorNz&VEQDt;n>6PHJxa>p&3v z8|F+Cc=6qw2*mRsI(>n>Ddc3<^o$EJ;e}|Bi1+%Ovh;YRsIKfLT(B8)hV%yTH(DkX zKivbtm>Zy|w1&Y2odGR+E_C5_H;T;O-$K!y>3sq)vpd~KNw1Z05e_IxLiJd$$aLd{ zmBG6<5b4+g(jO-~^JgQuP$}Y-|G>x_r$&gS{+o%%EyPq^DAYBx&h16g*`f2fFcG{6B++W6-|yJgp8ALDG3NWeBsjk4P$ z2BCajqVXy0ESGZIj9w=pNFVxc62QUKF*=}!Xw8uuVXi;##Mq)ZHK@&Dwth~x<@*>vR(t- z`UN2~dDwW_{hrGyUE$&=7<>@sRe;TbbU9AJDFt{;vhlDKl>Jrnakr|{?6YR;3tFh8 zjZLbO*(H{C`ze0*$pPU(A0AxLJRFkMp$)W<57Q)%s+2XYJ%(xN^Uonl?Hs$5`wR>- zxX7^;bvRLy01*k!S5l*BOP2@&zfPd2``6hyGm-(rG}P~BKg7bimEHRKLjh-*>5j;g z=1?(^TKFYP`J?j=?J^$PC@ut6U5JiQe6%14+f(gyXx+|XB9X4+)le`u-B5reK!L9; zAg6z4>lPzOUM$Vybe(ma9Et+ZY&wFVJ#8ngzxbwux}UvGvHWBKBrjA~oo?`eau`ba z4a&X{qS3hRW!-4UQlciSu6DBf4)#+c!o6X0te}Fk+}^7{s%5xZ=m`1StD{XV0EO=7 zg((lXqXXqJ)o`24}Off^vq5?FdpHs~)KdktJJAYG)r zcJZwxsJGzk?m&NSXWZMH3y02F08Jk_5|qXufJs5!^^3>t&OpBrT4CzdZ0@Tn^;!|B z4_)py(fZnDn`3FPC~n;FG`0GHCMu8_t}+n-22bwbeb^Gs?u^|qB{8@y`Tcq1bsjk4 z<8V?s0<4sa5l;Z#U6YynzP66ff`kaLsIVpbujqgYJ>^*lF?{x5J9Agz|Q;6w1_b#M?X*%7q@)& z5Bq3FBZa9M9P#_CT)ECS^7`O4 zfd#{&!*Wy*CennwNaIS`g~OTsPI6I-8n<$>6lUXYpOm_AGyPMkmMa!&?C}D6Tm!bH zRj~&+@I<*!`&)mhf^D^Jcg%g?Ke{}+$weGw07KQ9uT0*!MKO8Gkfs60m&Vyg4Q;1q zOV8CKK2vTC4tebJJKfATg{pP+zjOard>{KCD=4+ROjAw(72_yByi`46HM+z(wm7w+ ztlAYwJGu4HHb_9&z4C|^B^k+bWR!WUF%-FW&4ks4=`dMC%S6^m|?4XM)xP)})zI&_wBmkAk)Ky*=ho__;fneoZ>IfiF!2M0($dty$C_jWm{=N?m zy9~dnnq^-21K(~Ar5Z3+W~LTO1VPs~vIDjSmFqoz&+~Q*FcjT0d13);;=hTwW74JP z=NS(Y_yl`3#u_7f^-C;NfQJp9PQGOGpEQLaKcgBTOf3~gKrTyfzp z-MBL@Y|x7L-P}+VPEYC+p2lbNvNn#}GOKZt8x*Ccc%%o-W!@>=O_r2fv+oV#LaXw@t}(@j)kJg`8n&fx8ZuHei1z2nbjs7&2} zeBkY%wmc@L=z9-yp8)fF$V~yV=i;V&7*6f{)v01FfxH=yFi_T5$tWWhq6{7u>`uu$ z2bAz?xIw$6m7PWnn(JV4k+{UaXIb&vrHoH?6E_<}?htOtd6zS~?xm6Ajb>{n9G0HR-^dc%*=L)gi+f{u2$ zE|6AXUk`MBoc>^Z2uDvvS0blimcM)2!8tS-p+R3Mf;aaLtXpdap`75lsCzK(s2rz$ zh6R3H#_picuuO~N0m;Kw;JxM9oTX2(dFasnt0s7SGRLLX!iI~Td?i0bYL{(`O`$4 znEPu7O$X-pCpVDt1yhhmj)0A?$deb^$U3io=>_bDy;c)mq$-%4gQYNE#zOdzqXh(_ z)I&B8)E)U{XMFriIGSBan{WM2)`TQ^^R(K!cF`-p0un%^ZyS0Kj zZl@+#(jo1qr3eU!0?PEwtz}g3=7>$3MDftq2TW=JhmJYVXs#g#3iTwj|D02#LMSTN zvsGOsPmX7{(5zf-P112N+*5n>hdL+=_VC$^&8`jnEOn8_#8AW{y=k8T75V#1iU2fd zUpaxxvs7l{?{~+44WSZr`7KnQ^rA>QOmJ;|0e5UYMHF+cN6qs+^Y%);g~#td>ySY8 z{HpRTmzT3E93@y$-#OSM1Hi3$&ar@dOnAo!107`yZN zI|v$FgT10zzds+ZKjUf~-sB5(sClV1s(rBVflw912_w zf793hIYxcCpnv`v>3Yi)->Ok+?XaD{%m%0po?9aU?6L(kuJyT5-t8{ciwUcVMzruCA#h9;kH+!u z6rM*o@b$L{4J^l^SdwV2EJ0{e3hwR7U{kyzv0{>L)+ibG`mk(+u7v;zG!prb8J$YkAB%Ia8!}&=e}d z9GJvT_mJ)8C-*rhM9})HtDKpB?=v z00-IPleN%uTJB7rMJbVBAUa$ty4$b?hbAJl}$`F9T7%^Xv6i6-Ppl`?uivW)_ZA!{v>WKG#L5< z2@z*N#jLh$>#>-YIng6i1kaIZ1?jxhXI!Y+GMsYSBI)sUu>)x9LCJk00O#?1zwjem zEER#u$cqzF79nk7e6YIlezNuUjhUol@NdKJ=I!tV0Gv5cL;! zL26nz9_xACi{vFSF#TdlFEgmltIvL#BMwHbVbMyGm=4#MYE4;cRfM4%c;u}gD}srz9(th$ZXb_(lF6fRBU1uU zc|SYWIRI9$mlyvp;L57PE&;JRT>^xVs~*kk*19Lz7)zy34x|$VVdR9YzSdjSSzA%D zw`S^2a!QxQeeuRsYRJw6P-J0dusj_?oB2|!syFx%($snAHfrC+Fn9uR&s{gV(n5p; z77q=-DJmTwuK(E;l>vhxG{Gxt@@0Z@hQ*WN`S-r-*$<2p(pBA}GE7ZISxj||4LTHcaWCoay?vSP z$7qoNucmnW%^rWcxaOrK&k!5pW1&HBJI|$$`;oR!WD~@fj1zU}&T4_F%SLy^x+>Q0 zuyNdUA@Qp6wvlscDHXs@2dI5B=vV;ai6x%z$cDHNeQWshwEJ(Bs)KV+CLGIieXGu< zP=O?~emGK_jmX@g$^;7P(t+|iDusG0aIa~SuTZb;A)0~{m3*mRX54agO=W*vq>%R# zV0&Pypv8uFGq){`(0Y5VKww9@lQM*73X9^s!oM?Nec09WdO-FpO^V8?>qZwoZua+=Ymy>pD zs0rdX=6`)NV1XZ}SN`L>o_deWK#p8$I;shn0)II`j+!Q^kz?cb11H`o_VwbS4VpP} zSQzJ+%^r~YzOo_*>H)R*@5Ai9Rx#w&pbSy=)p2qnmD!1FzA|X(3y=*$VNOmiO_U<}&C&^ll@|bV14mup9z0MdEeLB^CxY|*L!(noWE_~swU5x1cN0GP z87}_%S>`6xqh49C(4LcTypaQzRinXDKVtTx(#Woo#)E|-NZqVWL~7Rq_iBv>=nK8R zIBCfPw9)x4C9?Q;x^7p75izFagl6?~1mJ!waXID_ab&o}*Jm)+82ct|CF?8APkcd| zB{7-vLe(tT+sY}wWlwSoaNyXD07cnTW>`j-&KHk+5Zr6`e}GJr1SXcR_qPwWTp{aD-?ROn_XQt+ zU^s3u<^aulS~iHutLFv08~Gs!typ6$+40>~Yw`d+t6Nav0F*3Wh`%5g4d#^oL!}LG zO!}f4Vg}~Q5{v@xknuJV$W-QWf)x85oT!<(=N#)0-F2XdS`m8^kQou!8|NboG`T*X zA58!iaR^V8B!bS_Gyq?p>RM260UiK)C`*!txYAEBs2E+qkvdR2ujhw@ZC-gp)na5W zXTMvH#*g`!!^4B|%7%%FgX3lSfm>*A@7y)|u*AL3h==avBUnqw@-Q2@!u@l6rsK^6 zsc);IqWA}|0XRX%xB_7WIo?NYHc9i33iIg4mH<)|j2l6SY6bJ^Kh4Vo;@)&H~o*=PM{^EPzczXBPeXBTnjE(3*ziX>7P=`0ecP?Tjf!n8XY|mR)@Ns2`Mu z1nH(Da@7gI?STg?5ncU+fcCocM~>)gbO=D3;bsU+1=~{lq)?|G0jYjmO?9{(XFc`g z%N!2^>u8G)liu37!Z@of47eGx9mrw6`XnYB>_eke}ZoZa6TU{cTN zJ`@F;lq9LykOP#GYS0W-h!ubK1tG$l$Fpd@GU1FUYHm;`w4*($;obrVM)GGH&0}MJ z3Vrt2rJP^7L~v65gKh(RfIdynXWm~~QCAIkfnYFiju&qF@FEq0Q8Ifjd9tML+p*Kp z(xE0tZQT=go}4jj-84Y1&1_Q_RN3#PVaa6{ILw4VPSB~1J~R8+*n4x)L0uR`is95} zN#o|QJ8@c3N_OI{TA~RPL~lk;u;AoTV%rTTH!Q3UYpP3@O3MOhwFq|Ynlo0ly{-6301CpZ;bb*iu%_jYoL6nq?3yg?|-YoCV83ux|Gk8~8(_{|cp( ziy-Ve-DU!lENuJM&A}d2)@#eKwn@?_qkojBC`7Io{XfCMEEI;Ao4p@xXAlIN)UxT^ zIPVzO@n1H`V22wKs;l!0n$8ZUaCx)Ww_D{Lpp1 zo2*lFBB)vK0=OFgO;bu<=A{uj^6Y0|-S|D}2?J>`m>+~5;i#UwoX$&eZsGV_sQzF-Nu2W*6KMMoy zTE?}NZzFR6h0goX=A!dMc|oo%GBHvKALG9vrQGyf9)YW=^9^UHsyV3$2@Z@Z=V5ki~HRHW9Zgd8`)|)9Qt0LZBXg*4rWn)`Yf4kuR zXI;F35D*EVlYzipfc5{j7wDH`+4=A;OMph$+fX;zDzBmv>%Io6;|2iwnEpb%SlQ1y zwNHnru)1p*F*ffz1fon<%|Y#4P`!FQD*E-xYmc6xWv(*NS1XE)nP)=uC-+^*GVlsV*uE4+iA6*|Kp4YH~$F@8AeEcaw zhK+=x9!l2+psg>-LF;n{rHLXeD8#R2P(LrW&0=T5eI5x!dV6SUdyo6qcws*2l0230 zYWLq9zoC$vZ?x+85GntJgAFP`!KSC(_~N(j;C*>xrCMtc?6@pGx^nXZbhTLonvndu zKWl2MA2B>GxVxsp(H?U0SNjv5g`R^ptO-{pXX=$P4x(LS3zy>L#3S5!pS8Rjuown< z`xM>NBpG@q*DC7R5JsUq+&B?|X5h2~+8_aX+OkvIrGo>>>v=}Qm7e}6G!@-gbZ;xRMRTR#HGrdg9Pb=6!7S$F(_Ngu3Zw}YXg$5s)k4YEP#oS zeY!`I^8sEk4P<3gN2ai2V8%u;>>YppoF{wG96TYa8sScw1SbkUp1d)B?Y_&@iR<9j z`xmx=g_CG`pt>N~ZYx5CM%UCq@4t3^&Y?)nD=AN_%BR|hej&A1Jc18MOM+HB-=dYo z&jq-Woq*QPp})FK<8wQo@Y~0GtNb-z@URy3M7nq^HOFj-jwl~wr>5U`k7;horfh;% zF^@!u7Hsa0=@C2urPJ3#@esa6G*`TGDT4Q3{37pjyKNDMB$+%s) ztkqUFDUY{cmK>mHhH+YSpE3mKK${ zu1j+k;FVDKT1zoQqJGQTTJE9Hm|o|o33hJ3Fc!4M8fksRg%#IAG0;Us(+rtJWju>o zx&q_ogJoxpw0{yrd{IdOl-xi5YOVr3tw+miLloxbDckva71UY$+m0Vpd3N$OXnZS( zzu5Nw_C6_UYbTcgV93Ae;zks3#M>}(Uv`AEGLRz|-$^cR69}Ysxij@zr!Ie1faB5@ z{qSh)ocR!Zedgd(6S8uk3$Wo54UtCr)S4qa-$sgtAld9|#=o z96O38eJV2sE<;sF<*B~$4}C%U=ih$HO$649y1mtjZPA28N{mx+=Ws)v^mD#@?^8xM z64^2@y$YY$-Mm2vP5DYzJ0FZc z!#GcCR@gjCOp$r@mGI9%{i2%ING)NN#R9z&yaC{4O%da}VS0cqT{hmkh70s#iO9~* z)NVGj6(VnJp3qlUrbb| zR18A^{|P~om+z~3ljh+>!|ifSf3o7SH{bxt*eI7j>ktS^1~Op)$}O1td@HC9W`T}* zeOc0*Vp2Y|sU+-D0aaR2>++TqHY3|V??T|1c^cNT908J#RP<%tF!zE=t+I8+1*@20 zLOB?KpU3RFfFBKFbDV}p zLW+ijgc_T_e|Ii48=X>GY4HsWgH>06e64??ic0UvW@@BqR{>p}^Z0s_A(xd{BR zG{BClL`*D~IZu&RgL zRq-gwQzK_8_+N-cv$F2Fd1+!)>xn0YU~AsQiLaxmWJi{Vg#|Yl|QJW$(P> zzL2<|PVn{T!0jeZ&2X+_0B6d)eJPJg9HrM@c{Y|Fq6i4avYoi-sBOg8U#-mJ)I$sP zg=C|F*y;z$5fMp_>O)Kj$Wz%1jBR^3Y8U=sp@xv~(ZpL6eWux%{9uF3iB4f;I|I>Y zWR$%%t`In0LOLQ{tUipbka-Q3y>lGcLl$*bh4>H(AO?`LjMwQoU{ zsq{}?+XVl~COSJ8dE+u{-#e!;)V^;z|$*@YTb^<#}jJw0x3mD+__8~iYM+VX9+-b$>%KM zAymKc5D@u0kr>T7rD=3n@%m1i%Ua4aKmtZ6Q^AS(l1g%J9Bv3KDmOOvouWHG0wB+l z|CFDdgb2yr8&42=PA>%S7BQ?x(xpR}b{JU3B-pg!a%ZRHvon>CZ7$78pzEiq2nTWi z(~BJxKHZ)asWoSZ&-A^T4(?$8#VFMdHcLV!mFu42UAB+qyn_ODlF^n z{~SUu10|qQ08BsJs>v@~t&Nd5UfH~bJ6cX5owE2 z`V@fmU4#mtLWG|G`=fwmXN|!AikKFHmwcVDqtewrY?g+WWm3@Wqk|-^^BdGjFqZng z1&TowV+T(PniX%;B`|Jxk$~%+JKJ7|Xrf2_LvuQ5ZfRxeVw3cSj)}rzTmaj9ifp`d zDYze7Ihod%IV5qqT6fflLs`Cx6ihf5>3}JE$v2mbM61rqS%hy4-(H6%3E|BD`4vYs zlQ8i25rR1iJ(DHm@SvtShXW-1QC*CULaq9Rv^t>m&7M{1uE9_WO>Xe}f5@tVnEGts z*lhRqj+z8lG~M?R7)MrJ<qpyTvlq=&MKRl4r#d?A9aTD6CBdLc>OVVHRZb7Twx)+C)wRoUVLIO3 zL-OLGfx_~qxh^WrCH52F8j**<&I`3PZZUBbI5(Mb>$rHnfghP>qjJm2MV`MulF^)L zHvS~WsyE`gpDY3sqX5lX4_&=ni6{b|D_w6JoGs0p#5hY=@h!2QkzIm7VV6HvBZk3n zrbPIwKVbE$njdtghR%F2^og4rS7#?3Vyw~>&5!Mt4Yg{2tlzVOYD~f35>TmEJ0haO zJP6k`$}8uyXjS@1Q|}{pERwF3;wH#IB9X~-mvIIgcHB__b8?ci!57I>ymBA-kXB*O znWm%PI;a4&^SEhj+Atu20)A)kED_&?9Jn#-gx22)5w>bvUUKsfyF` zlY^JVuN7KO)2G#Cqw~QLG}z>HpeKn>eq^_RrE5TPs-`yw!77L+M@|3C1=zSt18H6! zs+uAW_}S4m@EuM(JIl`*kf5I!delVf4EL{yEJ#x$>n(Pup|Zkl60;qJgOt}1n?rs|c5iJ5pq+-TF?nTFL&?5o)4ukW@(82CetR;O__tO*d( zK^X1q6LJw<#@4bvrfJF5igl)>Xlqw&^0P^_^ z+oeW{Bx?9DyHDp5Tm)bsgO*a>^x?cxU@6rKcceEfWyo1#A#V+$I^fs};+sP%X@aW1vdxC_~1Du zlOqJx{MPhmef>ysk7wTJYV$`3ME9rrnqooBp}n*V@LVLI3xHYys4MX--7^>7C=p4sRYK96+rOQ z%vXSV5+w!#-jb0%l5h?soQl#CV^arZZgJ2Qv)dN=sI@$f3H*%OM@fL)qF_Bm){~T6 z-d^rg>iD~70@4bw0QP)*Y89I63RY+xS_qNAVNN^ge;$GanD`S}{L|y6PHF3v0)K7b z?^q<#%+-=SHV^<@FyzLp`8vJkz`{(Nc>rQVN%KN2|9@1*uS*KEU_zJ3b)HNhel z^t2UzbfBK%TK^jDZxfCHepmps)I9L#%>PXjK&{4T0b|RoL5i68e{;kNtm!|8*m7UB z;76)9BmGlX`yG?^CkfPopMn`ATwBzBI4KKYs(?95=6|W9Z!IzL{T@NdxlMoFzb+DL z^%-qxFJ2EEcXYL%=1UyQv|mK?^B$)%4RKAdJbA5ha00Lzhv3g?Vru`Al`$oKb?v5q zYLU>C>u(7l3V!YVcP!wyi`VqJ+j~4EZFk8yly^+KLxZ20emZ*)F~dvRU#*CUyATaJ zuF3SD3N~He-|F)p<9t8C?^OI5^1 zB$Xg!ErTB5=luShrvF?Pn1Vk-F2@M|)MB07szOimFIn1K$6l&!n7W91d}PBKZn&8wIU+bpY`)@%Yml|O@DO( zJOJDDVG;n|S1q0kAlmo%I`yB&415Sod_<_Z-T|rLrH(@y>^s&pU)!v;7W`^*D|lUGhw?^U<}051m;o?`&oDLF5FIAzX8V+d*)w5(#>GVty7r>ny2U()(p4faKX z!nlvN$Vbb)O@XoYx=~}7+=`mCZzYx8S_Yv$w>QV859fXxU67Qs3?es$b^W&reAVXq zI+gyrRjp6ZQ!&`JA|4U+x~IKJ(wgnw%tVW2u?h6+ zG_cxS3!&OVFmFHCij#SfQ}E(+FYa5#1>My2%E70TCE0V3354R4-%N$+_E>HMdm}sL!9X1eS^&Eg?0D zNV{Vn2zD88Yh0jI!_O8|wV#!u>p7rCgKwuWM_+sIb5)@T`qHexG0W~02SP0ol$v>} z##q-V*TAy%qFZ@cnCD1jGtT$wPYr&{A4!Hj{e|gjOP8A45w3 zHYL_;a-oepz3w-Wz?{wuq`*J4epv~4uHrFDLtLW80P_l4E%2tA z=ITypBbQEpH1OWjY(%e>8Vt{|h)EL1o6)>SS&`JWjdN1Eqf1JVSjvzq!HZ8m`J`L1kUh<61A|<-$4aRD zeM&U;;Qdbxp!vVG{RO=s;2MBFWXKe;slaOblLV3k;1L0~2=LW{h;~P@gwqP>H8mF< zGUU)wDr&lm07}8^Spop51%53c`PEDIpD2o za3&Sm#U+|;HV9$J+GN)Qu%~WzYeJD0l*DtdKVog5a>$TX5P)Z%w*=jekpL|Cl?3eb z)~-fFh8&Cl0P?$c?;efG-rMYtc95N`0qKw-i(3Gv26p?J{=O~}DiOiZ{6mf^25@RV zzGvQl@WBV6vgKY-aLABB02}u4q4_niR|59{|Byid8v}pN$F~8!0q`MPl1IiRh-rUM zX!;M(4;ch-V%p!D{zHZg0yq)v5Act<{2?O-a3bK>I)EC<9|SOD>rz||cdjD1A{{$xFzuYTrJq!R~v%iy<*Li1S z0|2N*XQz1?=r58*j(3Q3=p+-we4cQ8s|Qkf(V_B*hl3xBK&?9oz#yz(fKbr=RD>zO zwua1?|5VEm6Asj^-AAKTnE8Mpd6}kaTS>Xv?sGi)b(QWq&@s1TeA(eRV6GLA^bm^v zL&F3MiJNCavcBCH6(8#W#{lA<0KiUwHAH>A9NCQ$C==wr5a*Ohd_&&RiU+;D=a`m> z>j6CHer_>k;0Ner#BHD5ESgi24~a?{XE8Tv4`npI(j4Pc8)GmH5im+|KjV7sf0b#6 zFLo{vCP_K$KK9q{WMhf-U%VJmXWS<^CHXeyO^ZM$i%qD9Y6Ps`b)%NjUrQLkmb}EX z<*sk*#BGzzCJ@5?&j+xkGGui!#cMJ$PCSg?H#TC%L&Q`ZMag2W9}%BI9J@X~uDKoC zH^PS}63_UTe<737lzQC_U_bs~O5)>8S;ru;ASx!x=gjTg$u<*Y@$fbI`eT}9SkMur z0^LpTm2qI^3qVbgUBlvCr1LvcfWTjv{^DmbJXZg~S zxjHb{k)3zv_%0VONZ!hST(5Kac+=YZJVi9wgJ0fK#KqpXNa5$;*k8mg?pAK(4IRdl zCoLJ_15;-d?`K7Y;UW#FMq0z`LEnB+C|s_5sen7DAE)RDhC`ARAB=pF=9)tR)an6yd8- zVFZOou+7>lQ4F5oVK~|nP>&BU2g!bdJpv;L3m+sP)r<6i$`4Z4g_|V3+yJA?6Y5ZZ z#$=Y4Qvs2}_ECBz)MXKSdGjceC{SM)U=p88}G|wiEKY=1hgPMi39#l_R|8hD( zES$1G&bp}9q(Xd-dOzkxpIglvC;mokKLS4@KXi$NfKbN29*9O!D|1P$D9)dTYi0;m zgfW7+nX;W|h2S_2zwi8H_|)!3$sa!uQzjvoo{cyTt13)Ij>DQeFL^>qRJ~c0G2)zI^WZSo^)8Aser0fBU|x|?ZIb7$@ImFYl*n>OCA#vbu34c$ zzK6kX#ME~I!$l=A12K7@dbij!^i5?FuD+!iCX98xXXPQdAN>`_0?=s$nIc~f^m=rBP^}usZ z7^XhTN*0UUUYZLN8hyq1%J}WkH1$N*+|=CJ^slM1De?SEgRfPGdD&$h^7mm^1$c%7 zn#!np`R#%+n+WXQluu(NwiowZOVVo*@fcAZ9~b{7PME@zQcA!`5RY$6#6_snQBL@Sh^hS) z+-;P^=9hq`;IgytBCc?~h&q2c|4V_$QJN9-t+vrf?g=t2GPzht>`M)z>6FY~C%Xi* zDeh2i9PT!*TvJMuzSqw6drfz5on5nCmfr>pM7$w>tN(V|=DfTzlY73g|LV8-nfYo< z`S!>002c?Bfu=t;Ueh`6>E3kpbk0A8hUSM3=8alUO?LB7*3O+mV*9aeob9u{&2q+>((X22!n7P1sJ(486_AX|V!mz|Zx4;c+n?2)2JsK5uW zlG@H+Y~yTug@;TaCl2$jf5i2sg$K|jVBzCbV+B!I6YCO8b|G8gLm_GC)eIdB!wkm? znF^}keDg{3iNAf#w;J#s_&lIuQ~AcY-!f)8iukAJfX%=Be_#I=lizVIwIC#Wr1M1A z?->3m`o!{Z&6#9%-rNxNF=sI=6HP|*M{`FXi{)iO#xACig$?S(%}z%=N5nZ8t{AS# z$G>>DwV7I2Qdyw zfeK*}*1bT3;JH9#{YZUGeZg>6`k}cnGd7Wso%~{KU0dI)#qk;BPlY;5fiM5k^i$4R zM8vOEa@=zGT;VN?XPU#TX94G3mceE{7L%`0uWK6N9);V#?hGf&3d?VnZn<>cq>dV=S_S-0{%%(@lIJvTG-9+qxBq9UiH6OXXPlSr4{cqC zJBE$&P(r#y`a!#nwXtqfY>j%Ix*4VUqJ^DKL&IKxr`n}Tys@TVrTt;i@A)>Lw(5h^ zg=wQ=Lu0dRmumR&sBhQZ7$iR;CLkj~?4DLwN#rVM^scouGw_PQoyukAe{-bAj)jMco`;TYuULVN#tXw|S;*60eSlU_~v~D0u-Ma%( z|1j?9#33{giAd_mR$d8+*n>(*?@5WDz{^n#uUyO|0oZz1hDeTSl)O)sLrKi7Wc_;KAYca$n=#cYbcm@FEs$Ij%kCl*tI(xuv)`Jt~gV&J6@# zhn?S_Vo=8a=N+*SDyHrL01nar1aN9O@BsiIJ5W`SHSqp@n7y4qBZ3<~|5cM$>1pH9 zicbYzOfDe`>Fir1)|<+HJr}_Y=j%`@SQzs8;N^9F<y@N9@xJ3#{B&czEnd5+(m12y8-{7D0j zF)@NyBpI#+jrje>Bga7EQ&yES6l4hO6MMj85+E>P>6Kg>H~65@4!JB0I%p(>H^l?m zoY5AX8M|Fx0zbAHylzA@nv=NR87f^L?(OYOQ5@LlKJ81~rL6EYceGkk9}EoCZV0NJ zGu`9Rri;yzd49S-{`cd_D(Laj<+WCoxkpyG-$Q15{(Vs|CSToB;cF2>7~uJ!etd-+ zR5q6z^mLmd^v4WFL}Me7yRU-8$@Gjwjbr%(6#-x!JP#l>!13$mxXiP^dHrE*mGQH8 z0u`-%$Mk%8RE-nXfxQ{1KfM4O8tHl;cbzE{!<-Q?UHN+?E!Uu%Q2vi9VY0x6-sl5q zZjT}Xyonp_=>Oph$a=p<2(10{WCE7653ym@_&C0F`X6kv|0U@Ew}(Ifm%IO8>)uL& zo#AbvWEN{|jRmvsj!8ta*XF+mn*3w$ggM275w#zNd4FlIvhOLeS5jjogw%ErDhm}? z+N9ID-L!T9J0g{E%wq|V?T|=iDw{sg;_(74xy;p6_z1ImTn;%RzAK< z`h;Hz-*{hJoYf)L+h$kzc0<=zbOhw4WS;{?ULMdTq|kgGu*Ruq+YFEkA+0+GFmXmL z$_(S4IhOguf_RC~m@-zfGpM%Mtt&i7fQPDi8yLxqgTLK@4J=}xx8EKP>gYyp+hXJ! z@L37S5UeHN>_+G1fOj0nyh`8H6V*kscdP7_+jnh0iFKy}zNmh)@;~iML7N((8hiMm zmLn=u@jxb-n~4SY7xqi529%-c9Qx^%^lSgQ=<=1R1E}|XF(zEMZm5@TUi?6Amb?_a zyO)71*LwfBU)?1QqAoc7sf(=k3x8#iyd%Vp>@0p?Pt|4d-rF9_Ppx^}gP^xQ>M@5$ z>;e;Al${rD_*YvDDj0U2v6_N3VztH*Jp3162qcDQ3LH_%rjy1U=zMx~N9(a*zo1OA z+gwt!pHy7)Y!VD@WcU8x6SwOAU@3EF7gx^WLLrwrDIH?z$s2^9$AT9x6M>L?hB6F^ zCAxFvewt5sQqhx=AJDm-_^8J)FC-p0(eJKA)=6?U^}`oyagB=`%IQ@Y-<5o~yrBOM z0*yHUmmaGTZ3RF_O6Bqy^@_K$&u|0k!AJ*&+I*f?rs`vbXJz!602hk0vN!K2H3U!D z3LiK~P-Sz5q#Bi2NYj1G!@XhvbL0MJL{}N?ZE`d0xtA-s*i+smrvZT$wdb5&x z+y^?Te5|+cvdf*GaG5Ya*{#2Ni%T>U{3Tcmz4LCb{8^VKs0e~DZ~)NwsbZ73ntye7 zxz9QdKY66hbso_$6%o7ozybd5h5#M;=!g`4~)V|qZdbu!ci5>tttDg3o@1HtuY>Y@eTk_5!D^n>lo9xA60hNXvLGjMTQFcDso8U)acXWOV;ze>oNh(q6bf7HebLY>cnJ6q^2_Z7MT4Bb=fF@&SQeb+oNh#!rjG?emb(_b=F zA5j1Sodgu^Q>h-P0_%V<4BGoD zZYI#}`5EPi_i>881VL{&OysE>FXOOPd0^Hd9ScQK`fNOi(5FNtgOz@uaDr1$G0*VT zCtz>8tue%pVDdZ@fV%ANJpn9gfM^`q`P>;tey5;CBeC&~LpNRnnbS11bU)P0|M zORLTo3u^T-K#+m~6Vaf*lC~>8qGU4P!cY_?Q92L;h50Jmj^wyZpQ)Z9Wago2~&iX(%$Q+_#ZL)11_~t+mlQkYju8d@QqxkaNYRT-^upmTI_+&shjkhYHIl>*#wox5Guk;%L zJw5S<+z-$NwcoEt(j8fL_+FMA?Y0Hp?G_JgpTz@A=ixXLE&n4@L--6HW4!}WNp6*l zraxx0Wi6ogkt7S3(ZHX$70xe8=0JRc)NZ(X?f$oCpPcr@N1-NQ!PTw-Q}Foofl`1w zHcAmz^$Ihcm|6^_;hWZ}_{U7Xqw_zpROZYfKyL5(UD9OuS-?1GBNb6?sINzy^T;D=_TP5iZID0Qpf)dgD6UamqDLlm(gc&)WDMXMu~?_0 zOG=-Ryhjka!b$NnT3b`R5+M=J&<*}dth}^HesN<2yh^tU^f7Sd$Mq@T!`z?i`6b|8rM*TEG=FUL?|azqK1Cx?k(7y= z`T!(D#*)bM(BC#k*J9uKc}JATKULNMMdl15@-E0lGmk660NJL;Th_=IjwDI5%0E^c zAY$Ju{a_z;sp-+StZ3$i%=X2}LA4x3&ro33mzO7qs=M?Yne-crn-pZP^Z*({Ii`T@ zh)d49pf|7*ysSCk(p+lr(}37VYfGRxdf^Z-qLNK~a%z#ZmdDcFDvu#$1;aq@wXvb8 z^mN2=zvtzLw0Fg{i<{yMe$B= zFD(TL8<68`kZak8{F-Wm7j6H<2F0rbn=9#He&QJzo(Qdg3jl$3L1~~wdJi2Z1eIyA zX00H=vF1<^t^BRP7}o|uLvS)<3Z$Y}MQVycdw(kJ{$mumd^_hA_{5WdBC3(>Pqe{f zLzC3T0Mny+t4QE*Fo005ehNu#k(|I260xHj_79>0-fAXKOjAKjnd|UufOkViw=KE_i#j$V z7X^QYPYs4La*@|Yki?0lq=>vG_DqvW3?0bfN-g|CPD~;9d>}uKn*P0V^Elh`_x#N7K6R09s^=^=|B7sJ2+9^iai~u<-f}GAF)a49l>)He&KKkgCwDR2FDc{2;4=@`u{{^cotjxj{=MSy zXy%^1%>lr6)MHjY1zS>tvm~s+7OdJRwYA#eUwXCabnW1AuvLbsLmAS#;5pzyK!3a~ z{szc#a9n|`Uqo@}laFBJz-1D|x#S1Mse|IU(KcQYRe9RyRk^VjbE272^g}KXespQ@j`!jtz#fV_-&#c5iOX;)%NvsV|XY` zZ%iq&8XU|H6BQHX7fXb%1fL8(1J+_ed^Wl-Oi6$nra#*Culc6wQ)yFiX8{zM{39X+ zW~u(vOc~kgibGlt~2<31yKx8>5?zpL4k?WCF2V}w{) zlRp8JO^qo*RD!gyR$FaA$(yGzs1q?|fe?Sl?>Rv@jt-u3MjV+L^W!u!iSYT_h&gnl z!r>#%&L9ZX+=%XB0?_S#$HkxxIMCMYL5FGQmFfM|BE?e%!RPi)-T0D%s-I(FDh$zN zz}&a?^k|-V=AIt+fDe#&&|lwc>P=zcnwCeShF?b<9RN^$%M*&Jq6A`U4h19;bWsAI zwYOiDO&EOkf_~gm@uz;D`S9iYTHntlFkr+E;xf&POb2_Kr6qY+{x>n$o<^cD{@%#_UDfOAKW zWi2bX>R$d3z)??aSrw)Ow1{mKV)uyO04x^=WS^S@>mv0&w!G6o)d!Qnrqt1YH2aXq zCpZ$HC_!|$cPsYqB*)cDOJwb(j8`3Mjc*Xit3%ip)+KQZL!E_tTOV;s?6BPmQj1wX zrTuWevu>r7d4VG%4wkH7-vplB)!KdnPTyV(y_`5u!q*DbQ^KkLn8%*~vF??|<_ZlK zvLLzT5dhSw7bpyLd(buR_<<2YYcKS$T<9kdF+o5;dtOXzVZNpkD}e*F??X|uRbjNf zk21t>1aQJQ;qh?HmTLjQ1QJs@GJs*1>F%%Iggr0=6N|)pV6vL3_xe5G79Y?XBbwWQ zn3-2@5CEcQ^0Nf?)LR7pBd#uK}ikgGLIy=vV-xwUO zQ-<`Z%4o3 zLZS810r>u{SsGNMj^-wR>HB_!sYu%z5&S}LCn3?l8UCgdrsW{~V!Wgzx=X^rpJAy` zuB*&ukS3EDc1woQJb!Ebva+xI8zUW)or{M>;616A4 zSL7V!btNod)1P>l*Iz>-3|6NDzS5lsN?dCE68nW_34GWKYqq)sdK45BOV%N5e-nwX zGy9lr9_|f36`pMx^?%cIQ10|z2z#v&a3wL-w#_^A#KwQ6(q`53S*t4xI0@V;oFbm? zNWtn>h?oiHRA?q+-jVBUbPd?~${+S(s=ghbRrw6{MxrVb*;cWWvlM|!b{poSM ze>nW2xNe5;jEg3t3A{{{CxP-e5p8fd8m9_xfq`@$x2QcQ2Y@dRux8J%U(v`dWmwLz z&MBd1M8*ES%ugU~a-_sE!mSka9p>^C@bg{ary5(gbWxRDhT2apU-cQ$c4ZB*i zr~h#}JNnh-9k%=O=dT;JQVC@o(nctoHT~EA4TW#CgHnl>(_K)eH@peou18i(9GbyD4#V}-Hv2O4@ zm7cR91Ljt0KQS7dC@m3-=IB^uw|Ek*`_)##g^Ah!+GIUF_A(Up@kL)!+s;kh%ho+&rmv~rOPJxnBTRFs%hsFfZ6P>P8cbk$A&hy1JQFW&dpEbzM`SrfK zu;WxXNu22MAdJ=?5t$`=7`(D~xzKL*aENkau*a=YSK5A({pPAyJymPdD@?#~#?O+`sn3HneY^SO1-P+lQ7~_q2fnVSC{`zK(Zv<3{zpE-N<0JCXe0 zfP<0jckMB=>)NF3OUiJgMJ2UIvA5FDR03~yX>WEJSolK45MXa3?3bR&tTpZI`--p` dN}>mhmDA{i{EM9J|DNFhRYfg@Dmi$_{{d&R7!&{i literal 0 HcmV?d00001 diff --git a/Assets/TrailEffect/Textures/swingFXRough.png b/Assets/TrailEffect/Textures/swingFXRough.png new file mode 100644 index 0000000000000000000000000000000000000000..fee914502b170f945468b442152df6d52d61d288 GIT binary patch literal 22769 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 literal 0 HcmV?d00001 diff --git a/Assets/TrailEffect/Utillities.meta b/Assets/TrailEffect/Utillities.meta new file mode 100644 index 0000000..8929b5b --- /dev/null +++ b/Assets/TrailEffect/Utillities.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: e0c6b2c9ac2b99d44a2fddaf4a1f2e1f +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Utillities/CircularBuffer.cs b/Assets/TrailEffect/Utillities/CircularBuffer.cs new file mode 100644 index 0000000..923dbe9 --- /dev/null +++ b/Assets/TrailEffect/Utillities/CircularBuffer.cs @@ -0,0 +1,286 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +namespace PigeonCoopToolkit.Utillities +{ + public class CircularBuffer : IList, ICollection, + IEnumerable, IEnumerable + { + /// + /// Creates a new instance of a with a + /// specified cache size. + /// + /// The maximal count of items to be stored within + /// the ring buffer. + public CircularBuffer(int capacity) + { + // validate capacity + if (capacity <= 0) + throw new ArgumentException("Must be greater than zero", "capacity"); + // set capacity and init the cache + Capacity = capacity; + _buffer = new T[capacity]; + } + + /// + /// the internal buffer + /// + T[] _buffer; + /// + /// The all-over position within the ring buffer. The position + /// increases continously by adding new items to the buffer. This + /// value is needed to calculate the current relative position within the + /// buffer. + /// + int _position; + /// + /// The current version of the buffer, this is required for a correct + /// exception handling while enumerating over the items of the buffer. + /// + long _version; + + /// + /// Gets or sets an item for a specified position within the ring buffer. + /// + /// The position to get or set an item. + /// The fond item at the specified position within the ring buffer. + /// + /// + public T this[int index] { + get { + // validate the index + if (index < 0 || index >= Count) + throw new IndexOutOfRangeException(); + // calculate the relative position within the rolling base array + int index2 = (_position - Count + index) % Capacity; + return _buffer[index2]; + } + set { Insert(index, value); } + } + + /// + /// Gets the maximal count of items within the ring buffer. + /// + public int Capacity { get; private set; } + /// + /// Get the current count of items within the ring buffer. + /// + public int Count { get; private set; } + + /// + /// Adds a new item to the buffer. + /// + /// The item to be added to the buffer. + public void Add(T item) { + // add a new item to the current relative position within the + // buffer and increase the position + _buffer[_position++ % Capacity] = item; + // increase the count if capacity is not yet reached + if (Count < Capacity) Count++; + // buffer changed; next version + _version++; + } + + /// + /// Clears the whole buffer and releases all referenced objects + /// currently stored within the buffer. + /// + public void Clear() { + for (int i = 0; i < Count; i++) + _buffer[i] = default(T); + _position = 0; + Count = 0; + _version++; + } + + /// + /// Determines if a specified item is currently present within + /// the buffer. + /// + /// The item to search for within the current + /// buffer. + /// True if the specified item is currently present within + /// the buffer; otherwise false. + public bool Contains(T item) { + int index = IndexOf(item); + return index != -1; + } + + /// + /// Copies the current items within the buffer to a specified array. + /// + /// The target array to copy the items of + /// the buffer to. + /// The start position witihn the target + /// array to start copying. + public void CopyTo(T[] array, int arrayIndex) { + for (int i = 0; i < Count; i++) { + array[i + arrayIndex] = _buffer[(_position - Count + i) % Capacity]; + } + } + + /// + /// Gets an enumerator over the current items within the buffer. + /// + /// An enumerator over the current items within the buffer. + /// + public IEnumerator GetEnumerator() { + long version = _version; + for (int i = 0; i < Count; i++) { + if (version != _version) + throw new InvalidOperationException("Collection changed"); + yield return this[i]; + } + } + + /// + /// Gets the position of a specied item within the ring buffer. + /// + /// The item to get the current position for. + /// The zero based index of the found item within the + /// buffer. If the item was not present within the buffer, this + /// method returns -1. + public int IndexOf(T item) { + // loop over the current count of items + for (int i = 0; i < Count; i++) { + // get the item at the relative position within the internal array + T item2 = _buffer[(_position - Count + i) % Capacity]; + // if both items are null, return true + if (null == item && null == item2) + return i; + // if equal return the position + if (item != null && item.Equals(item2)) + return i; + } + // nothing found + return -1; + } + + /// + /// Inserts an item at a specified position into the buffer. + /// + /// The position within the buffer to add + /// the new item. + /// The new item to be added to the buffer. + /// + /// + /// If the specified index is equal to the current count of items + /// within the buffer, the specified item will be added. + /// + /// Warning + /// Frequent usage of this method might become a bad idea if you are + /// working with a large buffer capacity. The insertion of an item + /// at a specified position within the buffer causes causes all present + /// items below the specified position to be moved one position. + /// + public void Insert(int index, T item) { + // validate index + if (index < 0 || index > Count) + throw new IndexOutOfRangeException(); + // add if index equals to count + if (index == Count) { + Add(item); + return; + } + + // get the maximal count of items to be moved + int count = Math.Min(Count, Capacity - 1) - index; + // get the relative position of the new item within the buffer + int index2 = (_position - Count + index) % Capacity; + + // move all items below the specified position + for (int i = index2 + count; i > index2; i--) { + int to = i % Capacity; + int from = (i - 1) % Capacity; + _buffer[to] = _buffer[from]; + } + + // set the new item + _buffer[index2] = item; + + // adjust storage information + if (Count < Capacity) { + Count++; + _position++; + } + // buffer changed; next version + _version++; + } + + /// + /// Removes a specified item from the current buffer. + /// + /// The item to be removed. + /// True if the specified item was successfully removed + /// from the buffer; otherwise false. + /// + /// Warning + /// Frequent usage of this method might become a bad idea if you are + /// working with a large buffer capacity. The removing of an item + /// requires a scan of the buffer to get the position of the specified + /// item. If the item was found, the deletion requires a move of all + /// items stored abouve the found position. + /// + public bool Remove(T item) { + // find the position of the specified item + int index = IndexOf(item); + // item was not found; return false + if (index == -1) + return false; + // remove the item at the specified position + RemoveAt(index); + return true; + } + + /// + /// Removes an item at a specified position within the buffer. + /// + /// The position of the item to be removed. + /// + /// + /// Warning + /// Frequent usage of this method might become a bad idea if you are + /// working with a large buffer capacity. The deletion requires a move + /// of all items stored abouve the found position. + /// + public void RemoveAt(int index) { + // validate the index + if (index < 0 || index >= Count) + throw new IndexOutOfRangeException(); + // move all items above the specified position one step + // closer to zeri + for (int i = index; i < Count - 1; i++) { + // get the next relative target position of the item + int to = (_position - Count + i) % Capacity; + // get the next relative source position of the item + int from = (_position - Count + i + 1) % Capacity; + // move the item + _buffer[to] = _buffer[from]; + } + // get the relative position of the last item, which becomes empty + // after deletion and set the item as empty + int last = (_position - 1) % Capacity; + _buffer[last] = default(T); + // adjust storage information + _position--; + Count--; + // buffer changed; next version + _version++; + } + + /// + /// Gets if the buffer is read-only. This method always returns false. + /// + bool ICollection.IsReadOnly { get { return false; } } + + /// + /// See generic implementation of . + /// + /// See generic implementation of . + /// + IEnumerator IEnumerable.GetEnumerator() { + return this.GetEnumerator(); + } + } +} diff --git a/Assets/TrailEffect/Utillities/CircularBuffer.cs.meta b/Assets/TrailEffect/Utillities/CircularBuffer.cs.meta new file mode 100644 index 0000000..eb81254 --- /dev/null +++ b/Assets/TrailEffect/Utillities/CircularBuffer.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 51a19be087405654c8b4b50c67fa9200 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Utillities/Editor.meta b/Assets/TrailEffect/Utillities/Editor.meta new file mode 100644 index 0000000..3bafe1c --- /dev/null +++ b/Assets/TrailEffect/Utillities/Editor.meta @@ -0,0 +1,5 @@ +fileFormatVersion: 2 +guid: 5bd6a89e61571ac4da1296f14bbb936e +folderAsset: yes +DefaultImporter: + userData: diff --git a/Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs b/Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs new file mode 100644 index 0000000..38db991 --- /dev/null +++ b/Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs @@ -0,0 +1,34 @@ +using UnityEditor; +using UnityEngine; + +namespace PigeonCoopToolkit.Utillities.Editor +{ + [CustomPropertyDrawer(typeof(Range))] + public class RangePropertyDrawer : PropertyDrawer + { + public override void OnGUI(UnityEngine.Rect position, SerializedProperty property, UnityEngine.GUIContent label) + { + SerializedProperty Min = property.FindPropertyRelative("Min"); + SerializedProperty Max = property.FindPropertyRelative("Max"); + Vector2 newMinMax = Vector2.zero; + position.height = 16; + EditorGUI.LabelField(position, label); + position.y += 20; + position.width = position.width / 2; + newMinMax.x = EditorGUI.FloatField(position, "Min", Min.floatValue); + position.x += position.width; + newMinMax.y = EditorGUI.FloatField(position, "Max", Max.floatValue); + + if (newMinMax.x > newMinMax.y) + newMinMax.x = newMinMax.y; + + Min.floatValue = newMinMax.x; + Max.floatValue = newMinMax.y; + } + + public override float GetPropertyHeight(SerializedProperty property, GUIContent label) + { + return base.GetPropertyHeight(property, label) + 20; + } + } +} \ No newline at end of file diff --git a/Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs.meta b/Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs.meta new file mode 100644 index 0000000..5769b0e --- /dev/null +++ b/Assets/TrailEffect/Utillities/Editor/RangePropertyDrawer.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1eefccc24adb7c54a990dc0f9e669651 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Utillities/GizmosExtra.cs b/Assets/TrailEffect/Utillities/GizmosExtra.cs new file mode 100644 index 0000000..05fa3c4 --- /dev/null +++ b/Assets/TrailEffect/Utillities/GizmosExtra.cs @@ -0,0 +1,33 @@ +using UnityEngine; + +namespace PigeonCoopToolkit.Utillities +{ + public static class GizmosExtra + { + + public static void GizmosDrawCircle(Vector3 position, Vector3 up, float size, int divisions) + { + Vector3 offset = (Quaternion.Euler(90,0,0) * (up* size)) ; + + for (int i = 0; i < divisions; i++) + { + + Vector3 newOffset = Quaternion.AngleAxis(360f / divisions, up) * offset; + Gizmos.DrawLine(position + offset, position + newOffset); + offset = newOffset; + } + } + + public static void GizmosDrawArrow(Vector3 from, Vector3 to, float arrowSize) + { + Gizmos.DrawLine(from, to); + + Vector3 dir = to - from; + dir = dir.normalized*arrowSize; + + Gizmos.DrawLine(to, to - Quaternion.Euler(0, 0, 45)*dir); + Gizmos.DrawLine(to, to - Quaternion.Euler(0, 0, -45)*dir); + + } + } +} diff --git a/Assets/TrailEffect/Utillities/GizmosExtra.cs.meta b/Assets/TrailEffect/Utillities/GizmosExtra.cs.meta new file mode 100644 index 0000000..dd47c41 --- /dev/null +++ b/Assets/TrailEffect/Utillities/GizmosExtra.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ac8be081485ba1141bd28334fe9eabec +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/Assets/TrailEffect/Utillities/Range.cs b/Assets/TrailEffect/Utillities/Range.cs new file mode 100644 index 0000000..99a8e7a --- /dev/null +++ b/Assets/TrailEffect/Utillities/Range.cs @@ -0,0 +1,15 @@ +namespace PigeonCoopToolkit.Utillities +{ + [System.Serializable] + public class Range + { + public float Min; + public float Max; + + public bool WithinRange(float value) + { + return Min <= value && Max >= value; + } + } + +} diff --git a/Assets/TrailEffect/Utillities/Range.cs.meta b/Assets/TrailEffect/Utillities/Range.cs.meta new file mode 100644 index 0000000..991f43d --- /dev/null +++ b/Assets/TrailEffect/Utillities/Range.cs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: db4c92c149ebf004a83b3776345ca8d4 +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: diff --git a/fie.csproj b/fie.csproj index 1d25091..d124c01 100644 --- a/fie.csproj +++ b/fie.csproj @@ -1852,6 +1852,27 @@ + + + + + + + + + + + + + + + + + + + + +