123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using System;
- using UnityEngine.Playables;
- namespace UnityEngine.Timeline
- {
-
-
-
- public class ParticleControlPlayable : PlayableBehaviour
- {
- const float kUnsetTime = float.MaxValue;
- float m_LastPlayableTime = kUnsetTime;
- float m_LastParticleTime = kUnsetTime;
- uint m_RandomSeed = 1;
-
-
-
-
-
-
-
- public static ScriptPlayable<ParticleControlPlayable> Create(PlayableGraph graph, ParticleSystem component, uint randomSeed)
- {
- if (component == null)
- return ScriptPlayable<ParticleControlPlayable>.Null;
- var handle = ScriptPlayable<ParticleControlPlayable>.Create(graph);
- handle.GetBehaviour().Initialize(component, randomSeed);
- return handle;
- }
-
-
-
- public ParticleSystem particleSystem { get; private set; }
-
-
-
-
-
- public void Initialize(ParticleSystem ps, uint randomSeed)
- {
- m_RandomSeed = Math.Max(1, randomSeed);
- particleSystem = ps;
- SetRandomSeed(particleSystem, m_RandomSeed);
- #if UNITY_EDITOR
- if (!Application.isPlaying && UnityEditor.PrefabUtility.IsPartOfPrefabInstance(ps))
- UnityEditor.PrefabUtility.prefabInstanceUpdated += OnPrefabUpdated;
- #endif
- }
- #if UNITY_EDITOR
-
-
-
-
- public override void OnPlayableDestroy(Playable playable)
- {
- if (!Application.isPlaying)
- UnityEditor.PrefabUtility.prefabInstanceUpdated -= OnPrefabUpdated;
- }
- void OnPrefabUpdated(GameObject go)
- {
-
- if (UnityEditor.PrefabUtility.GetRootGameObject(particleSystem) == go)
- m_LastPlayableTime = kUnsetTime;
- }
- #endif
- static void SetRandomSeed(ParticleSystem particleSystem, uint randomSeed)
- {
- if (particleSystem == null)
- return;
- particleSystem.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
- if (particleSystem.useAutoRandomSeed)
- {
- particleSystem.useAutoRandomSeed = false;
- particleSystem.randomSeed = randomSeed;
- }
- for (int i = 0; i < particleSystem.subEmitters.subEmittersCount; i++)
- {
- SetRandomSeed(particleSystem.subEmitters.GetSubEmitterSystem(i), ++randomSeed);
- }
- }
-
-
-
-
-
- public override void PrepareFrame(Playable playable, FrameData data)
- {
- if (particleSystem == null || !particleSystem.gameObject.activeInHierarchy)
- {
-
- m_LastPlayableTime = kUnsetTime;
- return;
- }
- var time = (float)playable.GetTime();
- var particleTime = particleSystem.time;
-
- if (m_LastPlayableTime > time || !Mathf.Approximately(particleTime, m_LastParticleTime))
- Simulate(time, true);
- else if (m_LastPlayableTime < time)
- Simulate(time - m_LastPlayableTime, false);
- m_LastPlayableTime = time;
- m_LastParticleTime = particleSystem.time;
- }
-
-
-
-
-
- public override void OnBehaviourPlay(Playable playable, FrameData info)
- {
- m_LastPlayableTime = kUnsetTime;
- }
-
-
-
-
-
- public override void OnBehaviourPause(Playable playable, FrameData info)
- {
- m_LastPlayableTime = kUnsetTime;
- }
- private void Simulate(float time, bool restart)
- {
- const bool withChildren = false;
- const bool fixedTimeStep = false;
- float maxTime = Time.maximumDeltaTime;
- if (restart)
- particleSystem.Simulate(0, withChildren, true, fixedTimeStep);
-
-
- while (time > maxTime)
- {
- particleSystem.Simulate(maxTime, withChildren, false, fixedTimeStep);
- time -= maxTime;
- }
- if (time > 0)
- particleSystem.Simulate(time, withChildren, false, fixedTimeStep);
- }
- }
- }
|