diff options
author | chai <215380520@qq.com> | 2023-10-27 11:05:14 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2023-10-27 11:05:14 +0800 |
commit | 766cdff5ffa72b65d7f106658d1603f47739b2ba (patch) | |
tree | 34d7799a94dfa9be182825577583c0fa6dc935f7 /ROUNDS/GeneralParticleSystem.cs |
+ init
Diffstat (limited to 'ROUNDS/GeneralParticleSystem.cs')
-rw-r--r-- | ROUNDS/GeneralParticleSystem.cs | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/ROUNDS/GeneralParticleSystem.cs b/ROUNDS/GeneralParticleSystem.cs new file mode 100644 index 0000000..8f3203a --- /dev/null +++ b/ROUNDS/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(); + } +} |