Skip to content

Instantly share code, notes, and snippets.

@Laumania
Created March 12, 2020 17:01
Show Gist options
  • Save Laumania/84a9e24e8878194e4196f6afcd68b744 to your computer and use it in GitHub Desktop.
Save Laumania/84a9e24e8878194e4196f6afcd68b744 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DarkTonic.MasterAudio;
using System;
using System.Linq;
[RequireComponent(typeof(ParticleSystem))]
public class FireworksParticleSoundSystem : MonoBehaviour
{
private ParticleSystem _parentParticleSystem;
[SoundGroup]
public string BornSound;
[SoundGroup]
public string DieSound;
private ExplosionPhysicsForceEffect _explosionPhysicsForceEffect;
private IDictionary<uint, ParticleSystem.Particle> _trackedParticles = new Dictionary<uint, ParticleSystem.Particle>();
void Start()
{
_parentParticleSystem = this.GetComponent<ParticleSystem>();
if (_parentParticleSystem == null)
Debug.LogError("Missing ParticleSystem!", this);
_explosionPhysicsForceEffect = this.GetComponent<ExplosionPhysicsForceEffect>();
}
void Update()
{
var liveParticles = new ParticleSystem.Particle[_parentParticleSystem.particleCount];
_parentParticleSystem.GetParticles(liveParticles);
var particleDelta = GetParticleDelta(liveParticles);
foreach (var particleAdded in particleDelta.Added)
{
ApplyExplosionForceInArea(particleAdded.position, true, true);
Messenger.Broadcast(MessengerEventIds.PlaySoundAtVector3, new PlaySoundAtVector3MessengerEvent(BornSound, particleAdded.position, delayBasedOnDistanceToListener: true));
}
foreach (var particleRemoved in particleDelta.Removed)
{
ApplyExplosionForceInArea(particleRemoved.position, true, true);
Messenger.Broadcast(MessengerEventIds.PlaySoundAtVector3, new PlaySoundAtVector3MessengerEvent(DieSound, particleRemoved.position, delayBasedOnDistanceToListener: true));
}
}
private ParticleDelta GetParticleDelta(ParticleSystem.Particle[] liveParticles)
{
var deltaResult = new ParticleDelta();
foreach (var activeParticle in liveParticles)
{
ParticleSystem.Particle foundParticle;
if(_trackedParticles.TryGetValue(activeParticle.randomSeed, out foundParticle))
{
_trackedParticles[activeParticle.randomSeed] = activeParticle;
}
else
{
deltaResult.Added.Add(activeParticle);
_trackedParticles.Add(activeParticle.randomSeed, activeParticle);
}
}
var updatedParticleAsDictionary = liveParticles.ToDictionary(x => x.randomSeed, x => x);
var dictionaryKeysAsList = _trackedParticles.Keys.ToList();
foreach (var dictionaryKey in dictionaryKeysAsList)
{
if (updatedParticleAsDictionary.ContainsKey(dictionaryKey) == false)
{
deltaResult.Removed.Add(_trackedParticles[dictionaryKey]);
_trackedParticles.Remove(dictionaryKey);
}
}
return deltaResult;
}
private void ApplyExplosionForceInArea(Vector3 position, bool applyPhysicsForce = true, bool applyShakeEffect = true)
{
if (_explosionPhysicsForceEffect != null)
_explosionPhysicsForceEffect.ApplyExplosionForce(position, applyPhysicsForce, applyShakeEffect);
}
private class ParticleDelta
{
public IList<ParticleSystem.Particle> Added { get; set; } = new List<ParticleSystem.Particle>();
public IList<ParticleSystem.Particle> Removed { get; set; } = new List<ParticleSystem.Particle>();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment