summaryrefslogtreecommitdiff
path: root/GameCode/GeneralParticleSystem.cs
diff options
context:
space:
mode:
Diffstat (limited to 'GameCode/GeneralParticleSystem.cs')
-rw-r--r--GameCode/GeneralParticleSystem.cs304
1 files changed, 304 insertions, 0 deletions
diff --git a/GameCode/GeneralParticleSystem.cs b/GameCode/GeneralParticleSystem.cs
new file mode 100644
index 0000000..8f3203a
--- /dev/null
+++ b/GameCode/GeneralParticleSystem.cs
@@ -0,0 +1,304 @@
+using System.Collections;
+using Sirenix.OdinInspector;
+using UnityEngine;
+using UnityEngine.Events;
+using UnityEngine.UI;
+
+public class GeneralParticleSystem : MonoBehaviour
+{
+ public GameObject particleObject;
+
+ public bool useTimeScale;
+
+ private ObjectPool particlePool;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public float randomXPos;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public float randomYPos;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public float rate = 10f;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public bool playOnAwake = true;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public bool playOnEnablee;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public bool loop;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public float duration = 2f;
+
+ [FoldoutGroup("Spawn settings", 0)]
+ public AnimationCurve sizeMultiplierOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f);
+
+ public AnimationCurve emissionMultiplierOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f);
+
+ public ObjectParticle particleSettings;
+
+ [FoldoutGroup("Global settings", 0)]
+ public float simulationSpeed = 1f;
+
+ [HideInInspector]
+ public float simulationSpeedMultiplier = 1f;
+
+ [FoldoutGroup("Global settings", 0)]
+ public float saturationMultiplier = 1f;
+
+ [FoldoutGroup("Events", 0)]
+ public UnityEvent startEvent;
+
+ [FoldoutGroup("Events", 0)]
+ public float startEventDelay;
+
+ [FoldoutGroup("Events", 0)]
+ public UnityEvent endEvent;
+
+ [FoldoutGroup("Events", 0)]
+ public float endEventDelay;
+
+ private float sizeOverTimeAnimationCurveLength;
+
+ private float sizeMultiplierOverTimeAnimationCurveLength;
+
+ private float alphaOverTimeAnimationCurveLength;
+
+ private float emissionOverTimeAnimationCurveLength;
+
+ private bool inited;
+
+ private Coroutine emissionLoop;
+
+ private float lastEmissionTime;
+
+ private bool isPlaying;
+
+ private void OnEnable()
+ {
+ isPlaying = false;
+ if (playOnEnablee)
+ {
+ Play();
+ }
+ }
+
+ private void Start()
+ {
+ if (playOnAwake)
+ {
+ Play();
+ }
+ Mask component = base.transform.parent.GetComponent<Mask>();
+ if ((bool)component)
+ {
+ component.showMaskGraphic = false;
+ }
+ }
+
+ private void Init()
+ {
+ if (!inited)
+ {
+ inited = true;
+ if (particleSettings.sizeOverTime.keys.Length > 1)
+ {
+ sizeOverTimeAnimationCurveLength = particleSettings.sizeOverTime.keys[particleSettings.sizeOverTime.keys.Length - 1].time - particleSettings.sizeOverTime.keys[0].time;
+ }
+ if (particleSettings.alphaOverTime.keys.Length > 1)
+ {
+ alphaOverTimeAnimationCurveLength = particleSettings.alphaOverTime.keys[particleSettings.alphaOverTime.keys.Length - 1].time - particleSettings.alphaOverTime.keys[0].time;
+ }
+ if (sizeMultiplierOverTime.keys.Length > 1)
+ {
+ sizeMultiplierOverTimeAnimationCurveLength = sizeMultiplierOverTime.keys[sizeMultiplierOverTime.keys.Length - 1].time - sizeMultiplierOverTime.keys[0].time;
+ }
+ if (emissionMultiplierOverTime.keys.Length > 1)
+ {
+ emissionOverTimeAnimationCurveLength = emissionMultiplierOverTime.keys[emissionMultiplierOverTime.keys.Length - 1].time - emissionMultiplierOverTime.keys[0].time;
+ }
+ particleObject.SetActive(value: false);
+ particlePool = new ObjectPool(particleObject, 100, base.transform);
+ }
+ }
+
+ public void StartLooping()
+ {
+ loop = true;
+ Play();
+ }
+
+ public void EndLooping()
+ {
+ loop = false;
+ if (emissionLoop != null)
+ {
+ StopCoroutine(emissionLoop);
+ }
+ }
+
+ [Button]
+ public void Play()
+ {
+ Init();
+ if (!isPlaying)
+ {
+ emissionLoop = StartCoroutine(DoPlay());
+ }
+ }
+
+ private void OnDisable()
+ {
+ Stop();
+ }
+
+ public void Stop()
+ {
+ isPlaying = false;
+ DisableAllParticles();
+ if (emissionLoop != null)
+ {
+ StopCoroutine(emissionLoop);
+ }
+ }
+
+ private void DisableAllParticles()
+ {
+ if (base.transform.childCount > 0)
+ {
+ for (int i = 0; i < base.transform.GetChild(0).childCount; i++)
+ {
+ base.transform.GetChild(0).GetChild(i).gameObject.SetActive(value: false);
+ }
+ }
+ }
+
+ private IEnumerator DoPlay()
+ {
+ isPlaying = true;
+ if (startEvent != null)
+ {
+ if (startEventDelay != 0f)
+ {
+ StartCoroutine(DelayEvent(startEvent, startEventDelay));
+ }
+ else
+ {
+ startEvent.Invoke();
+ }
+ }
+ float counter = 0f;
+ while (counter < duration)
+ {
+ CheckIfShouldEmit(counter / duration);
+ counter += (useTimeScale ? TimeHandler.deltaTime : Time.unscaledDeltaTime) * (simulationSpeed * simulationSpeedMultiplier);
+ yield return null;
+ }
+ isPlaying = false;
+ if (loop)
+ {
+ Play();
+ }
+ else if (endEvent != null)
+ {
+ if (endEventDelay != 0f)
+ {
+ StartCoroutine(DelayEvent(endEvent, endEventDelay));
+ }
+ else
+ {
+ endEvent.Invoke();
+ }
+ }
+ }
+
+ private void CheckIfShouldEmit(float currentAnimationTime)
+ {
+ if ((useTimeScale ? Time.time : Time.unscaledTime) > lastEmissionTime + 1f / rate / (simulationSpeed * simulationSpeedMultiplier) / emissionMultiplierOverTime.Evaluate(currentAnimationTime * emissionOverTimeAnimationCurveLength) * Time.timeScale)
+ {
+ StartCoroutine(DoPlarticleLife(currentAnimationTime));
+ lastEmissionTime = Time.time;
+ }
+ }
+
+ private IEnumerator DoPlarticleLife(float currentAnimationTime)
+ {
+ GameObject spawned = particlePool.GetObject();
+ float counter = 0f;
+ float t = particleSettings.lifetime;
+ Vector3 startSize = spawned.transform.localScale;
+ Vector3 modifiedStartSize = spawned.transform.localScale * particleSettings.size * sizeMultiplierOverTime.Evaluate(currentAnimationTime * sizeMultiplierOverTimeAnimationCurveLength);
+ Image img = spawned.GetComponent<Image>();
+ Color startColor = Color.magenta;
+ if ((bool)img)
+ {
+ startColor = img.color;
+ }
+ if ((bool)img)
+ {
+ float value = Random.value;
+ if (particleSettings.color != Color.magenta)
+ {
+ img.color = particleSettings.color;
+ }
+ if (particleSettings.randomColor != Color.magenta)
+ {
+ img.color = Color.Lerp(img.color, particleSettings.randomColor, value);
+ }
+ if (!particleSettings.singleRandomValueColor)
+ {
+ value = Random.value;
+ }
+ if (particleSettings.randomAddedColor != Color.black)
+ {
+ img.color += Color.Lerp(Color.black, particleSettings.randomAddedColor, value);
+ }
+ if (!particleSettings.singleRandomValueColor)
+ {
+ value = Random.value;
+ }
+ if (particleSettings.randomAddedSaturation != 0f || saturationMultiplier != 1f)
+ {
+ Color.RGBToHSV(img.color, out var H, out var S, out var V);
+ S += value * particleSettings.randomAddedSaturation;
+ S *= saturationMultiplier;
+ img.color = Color.HSVToRGB(H, S, V);
+ }
+ }
+ spawned.transform.Rotate(base.transform.forward * particleSettings.rotation);
+ spawned.transform.Rotate(base.transform.forward * Random.Range(0f - particleSettings.randomRotation, particleSettings.randomRotation));
+ spawned.transform.localPosition = Vector3.zero;
+ spawned.transform.position += base.transform.up * Random.Range(0f - randomYPos, randomYPos);
+ spawned.transform.position += base.transform.right * Random.Range(0f - randomXPos, randomXPos);
+ spawned.transform.position += base.transform.forward * Random.Range(-0.1f, 0.1f);
+ while (counter < t)
+ {
+ if (particleSettings.sizeOverTime.keys.Length > 1)
+ {
+ spawned.transform.localScale = modifiedStartSize * particleSettings.sizeOverTime.Evaluate(counter / t * sizeOverTimeAnimationCurveLength);
+ }
+ float num = particleSettings.alphaOverTime.Evaluate(counter / t * alphaOverTimeAnimationCurveLength);
+ if ((bool)img && img.color.a != num)
+ {
+ img.color = new Color(img.color.r, img.color.g, img.color.b, num);
+ }
+ counter += (useTimeScale ? TimeHandler.deltaTime : Time.unscaledDeltaTime) * (simulationSpeed * simulationSpeedMultiplier);
+ yield return null;
+ }
+ if ((bool)img)
+ {
+ img.color = startColor;
+ }
+ spawned.transform.localScale = startSize;
+ particlePool.ReleaseObject(spawned);
+ }
+
+ private IEnumerator DelayEvent(UnityEvent e, float t)
+ {
+ yield return new WaitForSeconds(t);
+ e?.Invoke();
+ }
+}