Code From ParticleControlPlayable.cs
public override void PrepareFrame(Playable playable, FrameData data)
{
if (particleSystem == null || !particleSystem.gameObject.activeInHierarchy)
return;
float localTime = (float)playable.GetTime();
bool shouldUpdate = Mathf.Approximately(m_LastTime, kUnsetTime) ||
!Mathf.Approximately(m_LastTime, localTime);
if (shouldUpdate)
{
float epsilon = Time.fixedDeltaTime * 0.5f;
float simTime = localTime;
float expectedDelta = simTime - m_LastTime;
// The first iteration includes the start delay. Evaluate(particleSystem.randomSeed) is how the particle system generates the random value internally.
float startDelay = particleSystem.main.startDelay.Evaluate(particleSystem.randomSeed);
float particleSystemDurationLoop0 = particleSystem.main.duration + startDelay;
// The particle system time does not include the start delay so we need to remove this for our own system time.
float expectedSystemTime = simTime > particleSystemDurationLoop0 ? m_SystemTime : m_SystemTime - startDelay;
// conditions for restart
bool restart = (simTime < m_LastTime) || // time went backwards
(simTime < epsilon) || // time is set to 0
Mathf.Approximately(m_LastTime, kUnsetTime) || // object disabled
(expectedDelta > particleSystem.main.duration) || // large jump (bug workaround)
!(Mathf.Abs(expectedSystemTime - particleSystem.time) < Time.maximumParticleDeltaTime); // particle system isn't where we left it
if (restart)
{
// work around for a bug where simulate(simTime, true, true) doesn't work on loops
particleSystem.Simulate(0, true, true);
particleSystem.Simulate(simTime, true, false);
m_SystemTime = simTime;
}
else
{
// ps.time will wrap, so we need to account for that in computing delta time
float particleSystemDuration = simTime > particleSystemDurationLoop0 ? particleSystem.main.duration : particleSystemDurationLoop0;
float fracTime = simTime % particleSystemDuration;
float deltaTime = fracTime - m_SystemTime;
if (deltaTime < -epsilon) // detect wrapping of ps.time
deltaTime = fracTime + particleSystemDurationLoop0 - m_SystemTime;
particleSystem.Simulate(deltaTime, true, false);
m_SystemTime += deltaTime;
}
m_LastTime = localTime;
}
}