r2mods/ilspy_dump/ror2_csproj/RoR2/ParticleLifetimeSoundPlayer.cs

172 lines
4.2 KiB
C#

using System.Collections.Generic;
using AK.Wwise;
using UnityEngine;
namespace RoR2;
public class ParticleLifetimeSoundPlayer : MonoBehaviour
{
private class ParticleLifetimeTracker
{
private static int idCounter;
public bool isActive;
private bool firedStart;
private bool firedEnd;
private float lifetimeTimeStamp;
private float startTimeTimeStamp;
private float endTimeTimeStamp;
private int localId;
private AK.Wwise.Event startEvent;
private AK.Wwise.Event endEvent;
private GameObject soundObject;
public ParticleLifetimeTracker(GameObject go)
{
soundObject = go;
}
public void Initialize(float currentTime, float lifeTime, float startTimeOffset, float endTimeOffset, ref AK.Wwise.Event _startEvent, ref AK.Wwise.Event _endEvent, bool debug)
{
localId = idCounter++;
lifetimeTimeStamp = currentTime + lifeTime;
startTimeTimeStamp = currentTime + startTimeOffset;
endTimeTimeStamp = lifetimeTimeStamp + endTimeOffset;
firedStart = false;
firedEnd = false;
isActive = true;
startEvent = _startEvent;
endEvent = _endEvent;
}
public void Update(float currentTime, bool debug)
{
if (isActive)
{
if (!firedStart && currentTime > startTimeTimeStamp)
{
firedStart = true;
startEvent?.Post(soundObject);
}
if (!firedEnd && currentTime > endTimeTimeStamp)
{
firedEnd = true;
endEvent?.Post(soundObject);
}
isActive = currentTime < lifetimeTimeStamp;
_ = !isActive && debug;
}
}
}
public ParticleSystem particleSystemToTrack;
[Tooltip("How long after a particle is born should the StartEvent be posted.")]
public float startTimeOffset;
[Tooltip("How long before/after a particle dies should the EndEvent be posted.")]
public float endTimeOffset;
[Tooltip("Displays a message whenever a new particle is born")]
public bool debugMessages;
public AK.Wwise.Event startEvent;
public AK.Wwise.Event endEvent;
[Tooltip("How long between particles should we wait before firing the next sound. -1 = no delay")]
public float soundCooldown = -1f;
private float lastParticleTrackedTimeStamp;
private ParticleSystem.Particle[] particleArray;
[Space(20f)]
[SerializeField]
public List<GameObject> soundObjects = new List<GameObject>();
private List<ParticleLifetimeTracker> particleTrackers = new List<ParticleLifetimeTracker>();
private void Awake()
{
if (particleSystemToTrack == null)
{
particleSystemToTrack = GetComponent<ParticleSystem>();
}
int count = soundObjects.Count;
for (int i = 0; i < count; i++)
{
particleTrackers.Add(new ParticleLifetimeTracker(soundObjects[i]));
}
if (particleSystemToTrack != null)
{
particleArray = new ParticleSystem.Particle[particleSystemToTrack.main.maxParticles];
}
}
private void LateUpdate()
{
if (particleSystemToTrack == null)
{
base.enabled = false;
return;
}
float time = Time.time;
UpdateExistingParticlePlayers(time);
if (particleSystemToTrack.isEmitting && !(time - lastParticleTrackedTimeStamp < soundCooldown))
{
DiscoverAndTrackNewParticles(time);
}
}
private void UpdateExistingParticlePlayers(float currentTime)
{
for (int i = 0; i < particleTrackers.Count; i++)
{
particleTrackers[i]?.Update(currentTime, debugMessages);
}
}
private ParticleLifetimeTracker FindAvailableParticleTracker()
{
int count = particleTrackers.Count;
for (int i = 0; i < count; i++)
{
if (!particleTrackers[i].isActive)
{
return particleTrackers[i];
}
}
return null;
}
private void DiscoverAndTrackNewParticles(float currentTime)
{
ParticleLifetimeTracker particleLifetimeTracker = FindAvailableParticleTracker();
if (particleLifetimeTracker == null)
{
return;
}
int particles = particleSystemToTrack.GetParticles(particleArray);
for (int i = 0; i < particles; i++)
{
ParticleSystem.Particle particle = particleArray[i];
if (Mathf.Approximately(particle.startLifetime, particle.remainingLifetime))
{
lastParticleTrackedTimeStamp = currentTime;
particleLifetimeTracker.Initialize(currentTime, particle.remainingLifetime, startTimeOffset, endTimeOffset, ref startEvent, ref endEvent, debugMessages);
break;
}
}
}
}