diff options
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables')
18 files changed, 1268 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs new file mode 100644 index 0000000..3efb818 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs @@ -0,0 +1,140 @@ +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Playable that controls the active state of a GameObject. + /// </summary> + public class ActivationControlPlayable : PlayableBehaviour + { + /// <summary> + /// The state of a GameObject's activeness when a PlayableGraph stops. + /// </summary> + public enum PostPlaybackState + { + /// <summary> + /// Set the GameObject to active when the PlayableGraph stops. + /// </summary> + Active, + + /// <summary> + /// Set the GameObject to inactive when the [[PlayableGraph]] stops. + /// </summary> + Inactive, + + /// <summary> + /// Revert the GameObject to the active state it was before the [[PlayableGraph]] started. + /// </summary> + Revert + } + + enum InitialState + { + Unset, + Active, + Inactive + } + + public GameObject gameObject = null; + public PostPlaybackState postPlayback = PostPlaybackState.Revert; + InitialState m_InitialState; + + /// <summary> + /// Creates a ScriptPlayable with an ActivationControlPlayable behaviour attached + /// </summary> + /// <param name="graph">PlayableGraph that will own the playable</param> + /// <param name="gameObject">The GameObject that triggered the graph build</param> + /// <param name="postPlaybackState">The state to leave the gameObject after the graph is stopped</param> + /// <returns>Returns a playable that controls activation of a game object</returns> + public static ScriptPlayable<ActivationControlPlayable> Create(PlayableGraph graph, GameObject gameObject, ActivationControlPlayable.PostPlaybackState postPlaybackState) + { + if (gameObject == null) + return ScriptPlayable<ActivationControlPlayable>.Null; + + var handle = ScriptPlayable<ActivationControlPlayable>.Create(graph); + var playable = handle.GetBehaviour(); + playable.gameObject = gameObject; + playable.postPlayback = postPlaybackState; + + return handle; + } + + /// <summary> + /// This function is called when the Playable play state is changed to Playables.PlayState.Playing. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">The information about this frame</param> + public override void OnBehaviourPlay(Playable playable, FrameData info) + { + if (gameObject == null) + return; + + gameObject.SetActive(true); + } + + /// <summary> + /// This function is called when the Playable play state is changed to PlayState.Paused. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">The information about this frame</param> + public override void OnBehaviourPause(Playable playable, FrameData info) + { + // OnBehaviourPause can be called if the graph is stopped for a variety of reasons + // the effectivePlayState will test if the pause is due to the clip being out of bounds + if (gameObject != null && info.effectivePlayState == PlayState.Paused) + { + gameObject.SetActive(false); + } + } + + /// <summary> + /// This function is called during the ProcessFrame phase of the PlayableGraph. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + /// <param name="userData">unused</param> + public override void ProcessFrame(Playable playable, FrameData info, object userData) + { + if (gameObject != null)// && !gameObject.activeSelf) + gameObject.SetActive(true); + } + + /// <summary> + /// This function is called when the PlayableGraph that owns this PlayableBehaviour starts. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + public override void OnGraphStart(Playable playable) + { + if (gameObject != null) + { + if (m_InitialState == InitialState.Unset) + m_InitialState = gameObject.activeSelf ? InitialState.Active : InitialState.Inactive; + } + } + + /// <summary> + /// This function is called when the Playable that owns the PlayableBehaviour is destroyed. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + public override void OnPlayableDestroy(Playable playable) + { + if (gameObject == null || m_InitialState == InitialState.Unset) + return; + + switch (postPlayback) + { + case PostPlaybackState.Active: + gameObject.SetActive(true); + break; + + case PostPlaybackState.Inactive: + gameObject.SetActive(false); + break; + + case PostPlaybackState.Revert: + gameObject.SetActive(m_InitialState == InitialState.Active); + break; + } + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs.meta new file mode 100644 index 0000000..a7763a6 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d20e4e177b86a2843805dd3894f41b42 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs new file mode 100644 index 0000000..0157958 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// This class is deprecated. It is recommended to use Playable Asset and Playable Behaviour derived classes instead. + /// </summary> + [Serializable] + [Obsolete("For best performance use PlayableAsset and PlayableBehaviour.")] + public class BasicPlayableBehaviour : ScriptableObject, IPlayableAsset, IPlayableBehaviour + { + public BasicPlayableBehaviour() {} + + /// <summary> + /// The playback duration in seconds of the instantiated Playable. + /// </summary> + public virtual double duration { get { return PlayableBinding.DefaultDuration; } } + + /// <summary> + ///A description of the outputs of the instantiated Playable. + /// </summary> + public virtual IEnumerable<PlayableBinding> outputs { get { return PlayableBinding.None; } } + + /// <summary> + /// <para>This function is called when the PlayableGraph that owns this PlayableBehaviour starts.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + public virtual void OnGraphStart(Playable playable) {} + + /// <summary> + /// <para>This function is called when the PlayableGraph that owns this PlayableBehaviour stops.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + public virtual void OnGraphStop(Playable playable) {} + + /// <summary> + /// <para>This function is called when the Playable that owns the PlayableBehaviour is created.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + public virtual void OnPlayableCreate(Playable playable) {} + + /// <summary> + /// <para>This function is called when the Playable that owns the PlayableBehaviour is destroyed.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + public virtual void OnPlayableDestroy(Playable playable) {} + + /// <summary> + /// <para>This function is called when the Playable play state is changed to Playables.PlayState.Playing.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public virtual void OnBehaviourPlay(Playable playable, FrameData info) {} + + /// <summary> + /// <para>This function is called when the Playable play state is changed to Playables.PlayState.Paused.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public virtual void OnBehaviourPause(Playable playable, FrameData info) {} + + /// <summary> + /// <para>This function is called during the PrepareFrame phase of the PlayableGraph.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public virtual void PrepareFrame(Playable playable, FrameData info) {} + + /// <summary> + /// <para>This function is called during the ProcessFrame phase of the PlayableGraph.</para> + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + /// <param name="playerData">The user data of the ScriptPlayableOutput that initiated the process pass.</param> + public virtual void ProcessFrame(Playable playable, FrameData info, object playerData) {} + + /// <summary> + /// Implement this method to have your asset inject playables into the given graph. + /// </summary> + /// <param name="graph">The graph to inject playables into.</param> + /// <param name="owner">The game object which initiated the build.</param> + /// <returns>The playable injected into the graph, or the root playable if multiple playables are injected.</returns> + public virtual Playable CreatePlayable(PlayableGraph graph, GameObject owner) + { + return ScriptPlayable<BasicPlayableBehaviour>.Create(graph, this); + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs.meta new file mode 100644 index 0000000..414366e --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fe03a7b0ba57a4d488b6c327ae16c335 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs new file mode 100644 index 0000000..e619617 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs @@ -0,0 +1,206 @@ +using System; +using UnityEngine; +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Playable Behaviour used to control a PlayableDirector. + /// </summary> + /// <remarks> + /// This playable is used to control other PlayableDirector components from a Timeline sequence. + /// </remarks> + public class DirectorControlPlayable : PlayableBehaviour + { + /// <summary> + /// The PlayableDirector being controlled by this PlayableBehaviour + /// </summary> + public PlayableDirector director; + + private bool m_SyncTime = false; + + private double m_AssetDuration = double.MaxValue; + + /// <summary> + /// Creates a Playable with a DirectorControlPlayable attached + /// </summary> + /// <param name="graph">The graph to inject the playable into</param> + /// <param name="director">The director to control</param> + /// <returns>Returns a Playable with a DirectorControlPlayable attached</returns> + public static ScriptPlayable<DirectorControlPlayable> Create(PlayableGraph graph, PlayableDirector director) + { + if (director == null) + return ScriptPlayable<DirectorControlPlayable>.Null; + + var handle = ScriptPlayable<DirectorControlPlayable>.Create(graph); + handle.GetBehaviour().director = director; + +#if UNITY_EDITOR + if (!Application.isPlaying && UnityEditor.PrefabUtility.IsPartOfPrefabInstance(director)) + UnityEditor.PrefabUtility.prefabInstanceUpdated += handle.GetBehaviour().OnPrefabUpdated; +#endif + + return handle; + } + + public override void OnPlayableDestroy(Playable playable) + { +#if UNITY_EDITOR + if (!Application.isPlaying) + UnityEditor.PrefabUtility.prefabInstanceUpdated -= OnPrefabUpdated; +#endif + if (director != null && director.playableAsset != null) + director.Stop(); + } + + /// <summary> + /// This function is called during the PrepareFrame phase of the PlayableGraph. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void PrepareFrame(Playable playable, FrameData info) + { + if (director == null || !director.isActiveAndEnabled || director.playableAsset == null) + return; + + // resync the time on an evaluate or a time jump (caused by loops, or some setTime calls) + m_SyncTime |= (info.evaluationType == FrameData.EvaluationType.Evaluate) || + DetectDiscontinuity(playable, info); + + SyncSpeed(info.effectiveSpeed); + SyncPlayState(playable.GetGraph(), playable.GetTime()); + } + + /// <summary> + /// This function is called when the Playable play state is changed to Playables.PlayState.Playing. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPlay(Playable playable, FrameData info) + { + m_SyncTime = true; + + if (director != null && director.playableAsset != null) + m_AssetDuration = director.playableAsset.duration; + } + + /// <summary> + /// This function is called when the Playable play state is changed to PlayState.Paused. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPause(Playable playable, FrameData info) + { + if (director != null && director.playableAsset != null) + { + if (info.effectivePlayState == PlayState.Playing) // graph was paused + director.Pause(); + else + director.Stop(); + } + } + + /// <summary> + /// This function is called during the ProcessFrame phase of the PlayableGraph. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + /// <param name="playerData">unused</param> + public override void ProcessFrame(Playable playable, FrameData info, object playerData) + { + if (director == null || !director.isActiveAndEnabled || director.playableAsset == null) + return; + + if (m_SyncTime || DetectOutOfSync(playable)) + { + UpdateTime(playable); + director.Evaluate(); + } + + m_SyncTime = false; + } + +#if UNITY_EDITOR + void OnPrefabUpdated(GameObject go) + { + // When the prefab asset is updated, we rebuild the graph to reflect the changes in editor + if (UnityEditor.PrefabUtility.GetRootGameObject(director) == go) + director.RebuildGraph(); + } + +#endif + + void SyncSpeed(double speed) + { + if (director.playableGraph.IsValid()) + { + int roots = director.playableGraph.GetRootPlayableCount(); + for (int i = 0; i < roots; i++) + { + var rootPlayable = director.playableGraph.GetRootPlayable(i); + if (rootPlayable.IsValid()) + { + rootPlayable.SetSpeed(speed); + } + } + } + } + + void SyncPlayState(PlayableGraph graph, double playableTime) + { + bool expectedFinished = (playableTime >= m_AssetDuration) && director.extrapolationMode == DirectorWrapMode.None; + if (graph.IsPlaying() && !expectedFinished) + director.Play(); + else + director.Pause(); + } + + bool DetectDiscontinuity(Playable playable, FrameData info) + { + return Math.Abs(playable.GetTime() - playable.GetPreviousTime() - info.m_DeltaTime * info.m_EffectiveSpeed) > DiscreteTime.tickValue; + } + + bool DetectOutOfSync(Playable playable) + { + double expectedTime = playable.GetTime(); + if (playable.GetTime() >= m_AssetDuration) + { + if (director.extrapolationMode == DirectorWrapMode.None) + return false; + else if (director.extrapolationMode == DirectorWrapMode.Hold) + expectedTime = m_AssetDuration; + else if (m_AssetDuration > float.Epsilon) // loop + expectedTime = expectedTime % m_AssetDuration; + } + + if (!Mathf.Approximately((float)expectedTime, (float)director.time)) + { +#if UNITY_EDITOR + double lastDelta = playable.GetTime() - playable.GetPreviousTime(); + if (UnityEditor.Unsupported.IsDeveloperBuild()) + Debug.LogWarningFormat("Internal Warning - Control track desync detected on {2} ({0:F10} vs {1:F10} with delta {3:F10}). Time will be resynchronized. Known to happen with nested control tracks", playable.GetTime(), director.time, director.name, lastDelta); +#endif + return true; + } + return false; + } + + // We need to handle loop modes explicitly since we are setting the time directly + void UpdateTime(Playable playable) + { + double duration = Math.Max(0.1, director.playableAsset.duration); + switch (director.extrapolationMode) + { + case DirectorWrapMode.Hold: + director.time = Math.Min(duration, Math.Max(0, playable.GetTime())); + break; + case DirectorWrapMode.Loop: + director.time = Math.Max(0, playable.GetTime() % duration); + break; + case DirectorWrapMode.None: + director.time = playable.GetTime(); + break; + } + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs.meta new file mode 100644 index 0000000..5f71a6f --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be156cc527d606b4aaac403e9843186e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs new file mode 100644 index 0000000..5d986ae --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs @@ -0,0 +1,27 @@ +namespace UnityEngine.Timeline +{ + /// <summary> + /// Interface that can be implemented by MonoBehaviours indicating that they receive time-related control calls from a PlayableGraph. + /// </summary> + /// <remarks> + /// Implementing this interface on MonoBehaviours attached to GameObjects under control by control-tracks will cause them to be notified when associated Timeline clips are active. + /// </remarks> + public interface ITimeControl + { + /// <summary> + /// Called each frame the Timeline clip is active. + /// </summary> + /// <param name="time">The local time of the associated Timeline clip.</param> + void SetTime(double time); + + /// <summary> + /// Called when the associated Timeline clip becomes active. + /// </summary> + void OnControlTimeStart(); + + /// <summary> + /// Called when the associated Timeline clip becomes deactivated. + /// </summary> + void OnControlTimeStop(); + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs.meta new file mode 100644 index 0000000..8d4a953 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5415c904c4fbc3e498253bc2866b37cd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs new file mode 100644 index 0000000..a83fc8b --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs @@ -0,0 +1,31 @@ +using System; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Use these flags to specify the notification behaviour. + /// </summary> + /// <see cref="UnityEngine.Playables.INotification"/> + [Flags] + [Serializable] + public enum NotificationFlags : short + { + /// <summary> + /// Use this flag to send the notification in Edit Mode. + /// </summary> + /// <remarks> + /// Sent on discontinuous jumps in time. + /// </remarks> + TriggerInEditMode = 1 << 0, + + /// <summary> + /// Use this flag to send the notification if playback starts after the notification time. + /// </summary> + Retroactive = 1 << 1, + + /// <summary> + /// Use this flag to send the notification only once when looping. + /// </summary> + TriggerOnce = 1 << 2, + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs.meta new file mode 100644 index 0000000..4eae696 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 983c76d87fb6f4f4597a526a4b2b5fd7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs new file mode 100644 index 0000000..a513d7c --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs @@ -0,0 +1,177 @@ +using System; +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Playable that synchronizes a particle system simulation. + /// </summary> + public class ParticleControlPlayable : PlayableBehaviour + { + const float kUnsetTime = -1; + float m_LastTime = kUnsetTime; + uint m_RandomSeed = 1; + + // particleSystem.time can not be relied on for an accurate time. It does not advance until a delta threshold is reached(fixedUpdate) and until the start delay has elapsed. + float m_SystemTime; + + /// <summary> + /// Creates a Playable with a ParticleControlPlayable behaviour attached + /// </summary> + /// <param name="graph">The PlayableGraph to inject the Playable into.</param> + /// <param name="component">The particle systtem to control</param> + /// <param name="randomSeed">A random seed to use for particle simulation</param> + /// <returns>Returns the created Playable.</returns> + 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; + } + + /// <summary> + /// The particle system to control + /// </summary> + public ParticleSystem particleSystem { get; private set; } + + /// <summary> + /// Initializes the behaviour with a particle system and random seed. + /// </summary> + /// <param name="ps"></param> + /// <param name="randomSeed"></param> + public void Initialize(ParticleSystem ps, uint randomSeed) + { + m_RandomSeed = Math.Max(1, randomSeed); + particleSystem = ps; + m_SystemTime = 0; + SetRandomSeed(); + + #if UNITY_EDITOR + if (!Application.isPlaying && UnityEditor.PrefabUtility.IsPartOfPrefabInstance(ps)) + UnityEditor.PrefabUtility.prefabInstanceUpdated += OnPrefabUpdated; + #endif + } + + #if UNITY_EDITOR + /// <summary> + /// This function is called when the Playable that owns the PlayableBehaviour is destroyed. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + public override void OnPlayableDestroy(Playable playable) + { + if (!Application.isPlaying) + UnityEditor.PrefabUtility.prefabInstanceUpdated -= OnPrefabUpdated; + } + + void OnPrefabUpdated(GameObject go) + { + // When the instance is updated from, this will cause the next evaluate to resimulate. + if (UnityEditor.PrefabUtility.GetRootGameObject(particleSystem) == go) + m_LastTime = kUnsetTime; + } + + #endif + + void SetRandomSeed() + { + particleSystem.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); + var systems = particleSystem.gameObject.GetComponentsInChildren<ParticleSystem>(); + uint seed = m_RandomSeed; + foreach (var ps in systems) + { + // don't overwrite user set random seeds + if (ps.useAutoRandomSeed) + { + ps.useAutoRandomSeed = false; + ps.randomSeed = seed; + seed++; + } + } + } + + /// <summary> + /// This function is called during the PrepareFrame phase of the PlayableGraph. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="data">A FrameData structure that contains information about the current frame context.</param> + 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; + + // if it's not looping, then the system time won't advance past the end of the duration + if (!particleSystem.main.loop) + expectedSystemTime = Math.Min(expectedSystemTime, particleSystem.main.duration); + + + // 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; + } + } + + /// <summary> + /// This function is called when the Playable play state is changed to Playables.PlayState.Playing. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPlay(Playable playable, FrameData info) + { + m_LastTime = kUnsetTime; + } + + /// <summary> + /// This function is called when the Playable play state is changed to PlayState.Paused. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPause(Playable playable, FrameData info) + { + m_LastTime = kUnsetTime; + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs.meta new file mode 100644 index 0000000..33db5b9 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f603edd7163537f44927ad2808147a25 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs new file mode 100644 index 0000000..f84c9ff --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs @@ -0,0 +1,158 @@ +using System; +using UnityEngine.Playables; +using UnityEngine.SceneManagement; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Playable that controls and instantiates a Prefab. + /// </summary> + public class PrefabControlPlayable : PlayableBehaviour + { + GameObject m_Instance; + +#if UNITY_EDITOR + private bool m_IsActiveCached; +#endif + + /// <summary> + /// Creates a Playable with a PrefabControlPlayable behaviour attached + /// </summary> + /// <param name="graph">The PlayableGraph to inject the Playable into.</param> + /// <param name="prefabGameObject">The prefab to instantiate from</param> + /// <param name="parentTransform">Transform to parent instance to. Can be null.</param> + /// <returns>Returns a Playabe with PrefabControlPlayable behaviour attached.</returns> + public static ScriptPlayable<PrefabControlPlayable> Create(PlayableGraph graph, GameObject prefabGameObject, Transform parentTransform) + { + if (prefabGameObject == null) + return ScriptPlayable<PrefabControlPlayable>.Null; + + var handle = ScriptPlayable<PrefabControlPlayable>.Create(graph); + handle.GetBehaviour().Initialize(prefabGameObject, parentTransform); + return handle; + } + + /// <summary> + /// The instance of the prefab created by this behaviour + /// </summary> + public GameObject prefabInstance + { + get { return m_Instance; } + } + + /// <summary> + /// Initializes the behaviour with a prefab and parent transform + /// </summary> + /// <param name="prefabGameObject">The prefab to instantiate from</param> + /// <param name="parentTransform">Transform to parent instance to. Can be null.</param> + /// <returns>The created instance</returns> + public GameObject Initialize(GameObject prefabGameObject, Transform parentTransform) + { + if (prefabGameObject == null) + throw new ArgumentNullException("Prefab cannot be null"); + + if (m_Instance != null) + { + Debug.LogWarningFormat("Prefab Control Playable ({0}) has already been initialized with a Prefab ({1}).", prefabGameObject.name, m_Instance.name); + } + else + { + #if UNITY_EDITOR + if (!Application.isPlaying) + { + m_Instance = (GameObject)UnityEditor.PrefabUtility.InstantiatePrefab(prefabGameObject, parentTransform); + UnityEditor.PrefabUtility.prefabInstanceUpdated += OnPrefabUpdated; + } + else + #endif + { + m_Instance = Object.Instantiate(prefabGameObject, parentTransform, false); + } + m_Instance.name = prefabGameObject.name + " [Timeline]"; + m_Instance.SetActive(false); + SetHideFlagsRecursive(m_Instance); + } + return m_Instance; + } + + /// <summary> + /// This function is called when the Playable that owns the PlayableBehaviour is destroyed. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + public override void OnPlayableDestroy(Playable playable) + { + if (m_Instance) + { + if (Application.isPlaying) + Object.Destroy(m_Instance); + else + Object.DestroyImmediate(m_Instance); + } + +#if UNITY_EDITOR + UnityEditor.PrefabUtility.prefabInstanceUpdated -= OnPrefabUpdated; +#endif + } + + /// <summary> + /// This function is called when the Playable play state is changed to Playables.PlayState.Playing. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPlay(Playable playable, FrameData info) + { + if (m_Instance == null) + return; + + m_Instance.SetActive(true); + +#if UNITY_EDITOR + m_IsActiveCached = true; +#endif + } + + /// <summary> + /// This function is called when the Playable play state is changed to PlayState.Paused. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPause(Playable playable, FrameData info) + { + // OnBehaviourPause can be called if the graph is stopped for a variety of reasons + // the effectivePlayState will test if the pause is due to the clip being out of bounds + if (m_Instance != null && info.effectivePlayState == PlayState.Paused) + { + m_Instance.SetActive(false); +#if UNITY_EDITOR + m_IsActiveCached = false; +#endif + } + } + +#if UNITY_EDITOR + void OnPrefabUpdated(GameObject go) + { + if (go == m_Instance) + { + SetHideFlagsRecursive(go); + go.SetActive(m_IsActiveCached); + } + } + +#endif + + static void SetHideFlagsRecursive(GameObject gameObject) + { + if (gameObject == null) + return; + + gameObject.hideFlags = HideFlags.DontSaveInBuild | HideFlags.DontSaveInEditor; + if (!Application.isPlaying) + gameObject.hideFlags |= HideFlags.HideInHierarchy; + foreach (Transform child in gameObject.transform) + { + SetHideFlagsRecursive(child.gameObject); + } + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs.meta new file mode 100644 index 0000000..c148dc2 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 439c018cf4619e94d9a92110ce0aa188 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs new file mode 100644 index 0000000..68ec80d --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs @@ -0,0 +1,85 @@ +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// A PlayableBehaviour that manages a component that implements the ITimeControl interface + /// </summary> + public class TimeControlPlayable : PlayableBehaviour + { + ITimeControl m_timeControl; + + bool m_started; + + /// <summary> + /// Creates a Playable with a TimeControlPlayable behaviour attached + /// </summary> + /// <param name="graph">The PlayableGraph to inject the Playable into.</param> + /// <param name="timeControl"></param> + /// <returns></returns> + public static ScriptPlayable<TimeControlPlayable> Create(PlayableGraph graph, ITimeControl timeControl) + { + if (timeControl == null) + return ScriptPlayable<TimeControlPlayable>.Null; + + var handle = ScriptPlayable<TimeControlPlayable>.Create(graph); + handle.GetBehaviour().Initialize(timeControl); + return handle; + } + + /// <summary> + /// Initializes the behaviour + /// </summary> + /// <param name="timeControl">Component that implements the ITimeControl interface</param> + public void Initialize(ITimeControl timeControl) + { + m_timeControl = timeControl; + } + + /// <summary> + /// This function is called during the PrepareFrame phase of the PlayableGraph. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void PrepareFrame(Playable playable, FrameData info) + { + Debug.Assert(m_started, "PrepareFrame has been called without OnControlTimeStart being called first."); + if (m_timeControl != null) + m_timeControl.SetTime(playable.GetTime()); + } + + /// <summary> + /// This function is called when the Playable play state is changed to Playables.PlayState.Playing. + /// </summary> + /// <param name="playable">The Playable that owns the current PlayableBehaviour.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPlay(Playable playable, FrameData info) + { + if (m_timeControl == null) + return; + + if (!m_started) + { + m_timeControl.OnControlTimeStart(); + m_started = true; + } + } + + /// <summary> + /// This function is called when the Playable play state is changed to PlayState.Paused. + /// </summary> + /// <param name="playable">The playable this behaviour is attached to.</param> + /// <param name="info">A FrameData structure that contains information about the current frame context.</param> + public override void OnBehaviourPause(Playable playable, FrameData info) + { + if (m_timeControl == null) + return; + + if (m_started) + { + m_timeControl.OnControlTimeStop(); + m_started = false; + } + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs.meta new file mode 100644 index 0000000..5ce09ad --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1db879070d9a45f4c86cdf5e59616df5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs new file mode 100644 index 0000000..66a31d1 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// Use this PlayableBehaviour to send notifications at a given time. + /// </summary> + /// <seealso cref="UnityEngine.Timeline.NotificationFlags"/> + public class TimeNotificationBehaviour : PlayableBehaviour + { + struct NotificationEntry + { + public double time; + public INotification payload; + public bool notificationFired; + public NotificationFlags flags; + + public bool triggerInEditor + { + get { return (flags & NotificationFlags.TriggerInEditMode) != 0; } + } + public bool prewarm + { + get { return (flags & NotificationFlags.Retroactive) != 0; } + } + public bool triggerOnce + { + get { return (flags & NotificationFlags.TriggerOnce) != 0; } + } + } + + readonly List<NotificationEntry> m_Notifications = new List<NotificationEntry>(); + double m_PreviousTime; + bool m_NeedSortNotifications; + + Playable m_TimeSource; + + /// <summary> + /// Sets an optional Playable that provides duration and Wrap mode information. + /// </summary> + /// <remarks> + /// timeSource is optional. By default, the duration and Wrap mode will come from the current Playable. + /// </remarks> + public Playable timeSource + { + set { m_TimeSource = value; } + } + + /// <summary> + /// Creates and initializes a ScriptPlayable with a TimeNotificationBehaviour. + /// </summary> + /// <param name="graph">The playable graph.</param> + /// <param name="duration">The duration of the playable.</param> + /// <param name="loopMode">The loop mode of the playable.</param> + /// <returns>A new TimeNotificationBehaviour linked to the PlayableGraph.</returns> + public static ScriptPlayable<TimeNotificationBehaviour> Create(PlayableGraph graph, double duration, DirectorWrapMode loopMode) + { + var notificationsPlayable = ScriptPlayable<TimeNotificationBehaviour>.Create(graph); + notificationsPlayable.SetDuration(duration); + notificationsPlayable.SetTimeWrapMode(loopMode); + notificationsPlayable.SetPropagateSetTime(true); + return notificationsPlayable; + } + + /// <summary> + /// Adds a notification to be sent with flags, at a specific time. + /// </summary> + /// <param name="time">The time to send the notification.</param> + /// <param name="payload">The notification.</param> + /// <param name="flags">The notification flags that determine the notification behaviour. This parameter is set to Retroactive by default.</param> + /// <seealso cref="UnityEngine.Timeline.NotificationFlags"/> + public void AddNotification(double time, INotification payload, NotificationFlags flags = NotificationFlags.Retroactive) + { + m_Notifications.Add(new NotificationEntry + { + time = time, + payload = payload, + flags = flags + }); + m_NeedSortNotifications = true; + } + + /// <summary> + /// This method is called when the PlayableGraph that owns this PlayableBehaviour starts. + /// </summary> + /// <param name="playable">The reference to the playable associated with this PlayableBehaviour.</param> + public override void OnGraphStart(Playable playable) + { + SortNotifications(); + for (var i = 0; i < m_Notifications.Count; i++) + { + var notification = m_Notifications[i]; + notification.notificationFired = false; + m_Notifications[i] = notification; + } + + m_PreviousTime = playable.GetTime(); + } + + /// <summary> + /// This method is called when the Playable play state is changed to PlayState.Paused + /// </summary> + /// <param name="playable">The reference to the playable associated with this PlayableBehaviour.</param> + /// <param name="info">Playable context information such as weight, evaluationType, and so on.</param> + public override void OnBehaviourPause(Playable playable, FrameData info) + { + if (playable.IsDone()) + { + SortNotifications(); + for (var i = 0; i < m_Notifications.Count; i++) + { + var e = m_Notifications[i]; + if (!e.notificationFired) + { + var duration = playable.GetDuration(); + var canTrigger = m_PreviousTime <= e.time && e.time <= duration; + if (canTrigger) + { + Trigger_internal(playable, info.output, ref e); + m_Notifications[i] = e; + } + } + } + } + } + + /// <summary> + /// This method is called during the PrepareFrame phase of the PlayableGraph. + /// </summary> + /// <remarks> + /// Called once before processing starts. + /// </remarks> + /// <param name="playable">The reference to the playable associated with this PlayableBehaviour.</param> + /// <param name="info">Playable context information such as weight, evaluationType, and so on.</param> + public override void PrepareFrame(Playable playable, FrameData info) + { + // Never trigger on scrub + if (info.evaluationType == FrameData.EvaluationType.Evaluate) + { + return; + } + + SyncDurationWithExternalSource(playable); + SortNotifications(); + var currentTime = playable.GetTime(); + + // Fire notifications from previousTime till the end + if (info.timeLooped) + { + var duration = playable.GetDuration(); + TriggerNotificationsInRange(m_PreviousTime, duration, info, playable, true); + var dx = playable.GetDuration() - m_PreviousTime; + var nFullTimelines = (int)((info.deltaTime * info.effectiveSpeed - dx) / playable.GetDuration()); + for (var i = 0; i < nFullTimelines; i++) + { + TriggerNotificationsInRange(0, duration, info, playable, false); + } + TriggerNotificationsInRange(0, currentTime, info, playable, false); + } + else + { + var pt = playable.GetTime(); + TriggerNotificationsInRange(m_PreviousTime, pt, info, + playable, true); + } + + for (var i = 0; i < m_Notifications.Count; ++i) + { + var e = m_Notifications[i]; + if (e.notificationFired && CanRestoreNotification(e, info, currentTime, m_PreviousTime)) + { + Restore_internal(ref e); + m_Notifications[i] = e; + } + } + + m_PreviousTime = playable.GetTime(); + } + + void SortNotifications() + { + if (m_NeedSortNotifications) + { + m_Notifications.Sort((x, y) => x.time.CompareTo(y.time)); + m_NeedSortNotifications = false; + } + } + + static bool CanRestoreNotification(NotificationEntry e, FrameData info, double currentTime, double previousTime) + { + if (e.triggerOnce) + return false; + if (info.timeLooped) + return true; + + //case 1111595: restore the notification if the time is manually set before it + return previousTime > currentTime && currentTime <= e.time; + } + + void TriggerNotificationsInRange(double start, double end, FrameData info, Playable playable, bool checkState) + { + if (start <= end) + { + var playMode = Application.isPlaying; + for (var i = 0; i < m_Notifications.Count; i++) + { + var e = m_Notifications[i]; + if (e.notificationFired && (checkState || e.triggerOnce)) + continue; + + var notificationTime = e.time; + if (e.prewarm && notificationTime < end && (e.triggerInEditor || playMode)) + { + Trigger_internal(playable, info.output, ref e); + m_Notifications[i] = e; + } + else + { + if (notificationTime < start || notificationTime > end) + continue; + + if (e.triggerInEditor || playMode) + { + Trigger_internal(playable, info.output, ref e); + m_Notifications[i] = e; + } + } + } + } + } + + void SyncDurationWithExternalSource(Playable playable) + { + if (m_TimeSource.IsValid()) + { + playable.SetDuration(m_TimeSource.GetDuration()); + playable.SetTimeWrapMode(m_TimeSource.GetTimeWrapMode()); + } + } + + static void Trigger_internal(Playable playable, PlayableOutput output, ref NotificationEntry e) + { + output.PushNotification(playable, e.payload); + e.notificationFired = true; + } + + static void Restore_internal(ref NotificationEntry e) + { + e.notificationFired = false; + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs.meta new file mode 100644 index 0000000..593b6c2 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: afeb55855d7a63b45ba6f8bd97599202 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |
