summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Runtime
diff options
context:
space:
mode:
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs71
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs29
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs93
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs93
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs326
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs54
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs971
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs15
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs47
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs102
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs34
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs21
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs76
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs33
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs13
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs45
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs133
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs129
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs85
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs406
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs14
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs226
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs46
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs271
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs110
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs21
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs17
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs111
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs31
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs15
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs53
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs168
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs28
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs19
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs5
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs22
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs72
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs248
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs76
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs26
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs20
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs140
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ActivationControlPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs91
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/BasicScriptPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs206
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/DirectorControlPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs27
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ITimeControl.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs31
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/NotificationFlags.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs177
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/ParticleControlPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs158
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/PrefabControlPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs85
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeControlPlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs254
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables/TimeNotificationBehaviour.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs28
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs23
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs34
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs455
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs255
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs222
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs821
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs310
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs1264
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef6
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef.meta7
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities.meta8
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs266
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs133
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs92
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs51
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs102
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs17
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs54
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs212
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs131
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs90
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs30
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta11
156 files changed, 11029 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation.meta
new file mode 100644
index 0000000..ed3ac63
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d0cd29fb1ad218b48b814bc3e6d8ac0e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs
new file mode 100644
index 0000000..61054f7
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs
@@ -0,0 +1,71 @@
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ class ActivationMixerPlayable : PlayableBehaviour
+ {
+ ActivationTrack.PostPlaybackState m_PostPlaybackState;
+ bool m_BoundGameObjectInitialStateIsActive;
+
+ private GameObject m_BoundGameObject;
+
+
+ public static ScriptPlayable<ActivationMixerPlayable> Create(PlayableGraph graph, int inputCount)
+ {
+ return ScriptPlayable<ActivationMixerPlayable>.Create(graph, inputCount);
+ }
+
+ public ActivationTrack.PostPlaybackState postPlaybackState
+ {
+ get { return m_PostPlaybackState; }
+ set { m_PostPlaybackState = value; }
+ }
+
+ public override void OnPlayableDestroy(Playable playable)
+ {
+ if (m_BoundGameObject == null)
+ return;
+
+ switch (m_PostPlaybackState)
+ {
+ case ActivationTrack.PostPlaybackState.Active:
+ m_BoundGameObject.SetActive(true);
+ break;
+ case ActivationTrack.PostPlaybackState.Inactive:
+ m_BoundGameObject.SetActive(false);
+ break;
+ case ActivationTrack.PostPlaybackState.Revert:
+ m_BoundGameObject.SetActive(m_BoundGameObjectInitialStateIsActive);
+ break;
+ case ActivationTrack.PostPlaybackState.LeaveAsIs:
+ default:
+ break;
+ }
+ }
+
+ public override void ProcessFrame(Playable playable, FrameData info, object playerData)
+ {
+ if (m_BoundGameObject == null)
+ {
+ m_BoundGameObject = playerData as GameObject;
+ m_BoundGameObjectInitialStateIsActive = m_BoundGameObject != null && m_BoundGameObject.activeSelf;
+ }
+
+ if (m_BoundGameObject == null)
+ return;
+
+ int inputCount = playable.GetInputCount();
+ bool hasInput = false;
+ for (int i = 0; i < inputCount; i++)
+ {
+ if (playable.GetInputWeight(i) > 0)
+ {
+ hasInput = true;
+ break;
+ }
+ }
+
+ m_BoundGameObject.SetActive(hasInput);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs.meta
new file mode 100644
index 0000000..7ce2073
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationMixerPlayable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e165a99d845c10e4ea0f546e542e8684
+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/Activation/ActivationPlayableAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs
new file mode 100644
index 0000000..7304741
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs
@@ -0,0 +1,29 @@
+#if UNITY_EDITOR
+using System.ComponentModel;
+#endif
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Playable Asset class for Activation Tracks
+ /// </summary>
+#if UNITY_EDITOR
+ [DisplayName("Activation Clip")]
+#endif
+ class ActivationPlayableAsset : PlayableAsset, ITimelineClipAsset
+ {
+ /// <summary>
+ /// Returns a description of the features supported by activation clips
+ /// </summary>
+ public ClipCaps clipCaps { get { return ClipCaps.None; } }
+
+ /// <summary>
+ /// Overrides PlayableAsset.CreatePlayable() to inject needed Playables for an activation asset
+ /// </summary>
+ public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
+ {
+ return Playable.Create(graph);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs.meta
new file mode 100644
index 0000000..e22155a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationPlayableAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fde0d25a170598d46a0b9dc16b4527a5
+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/Activation/ActivationTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs
new file mode 100644
index 0000000..8e06ddb
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs
@@ -0,0 +1,93 @@
+using System;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Track that can be used to control the active state of a GameObject.
+ /// </summary>
+ [Serializable]
+ [TrackClipType(typeof(ActivationPlayableAsset))]
+ [TrackBindingType(typeof(GameObject))]
+ [ExcludeFromPreset]
+ public class ActivationTrack : TrackAsset
+ {
+ [SerializeField]
+ PostPlaybackState m_PostPlaybackState = PostPlaybackState.LeaveAsIs;
+ ActivationMixerPlayable m_ActivationMixer;
+
+ /// <summary>
+ /// Specify what state to leave the GameObject in after the Timeline has finished playing.
+ /// </summary>
+ public enum PostPlaybackState
+ {
+ /// <summary>
+ /// Set the GameObject to active.
+ /// </summary>
+ Active,
+
+ /// <summary>
+ /// Set the GameObject to Inactive.
+ /// </summary>
+ Inactive,
+
+ /// <summary>
+ /// Revert the GameObject to the state in was in before the Timeline was playing.
+ /// </summary>
+ Revert,
+
+ /// <summary>
+ /// Leave the GameObject in the state it was when the Timeline was stopped.
+ /// </summary>
+ LeaveAsIs
+ }
+
+ internal override bool CanCompileClips()
+ {
+ return !hasClips || base.CanCompileClips();
+ }
+
+ /// <summary>
+ /// Specifies what state to leave the GameObject in after the Timeline has finished playing.
+ /// </summary>
+ public PostPlaybackState postPlaybackState
+ {
+ get { return m_PostPlaybackState; }
+ set { m_PostPlaybackState = value; UpdateTrackMode(); }
+ }
+
+ /// <inheritdoc/>
+ public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
+ {
+ var mixer = ActivationMixerPlayable.Create(graph, inputCount);
+ m_ActivationMixer = mixer.GetBehaviour();
+
+ UpdateTrackMode();
+
+ return mixer;
+ }
+
+ internal void UpdateTrackMode()
+ {
+ if (m_ActivationMixer != null)
+ m_ActivationMixer.postPlaybackState = m_PostPlaybackState;
+ }
+
+ /// <inheritdoc/>
+ public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
+ {
+ var gameObject = GetGameObjectBinding(director);
+ if (gameObject != null)
+ {
+ driver.AddFromName(gameObject, "m_IsActive");
+ }
+ }
+
+ /// <inheritdoc/>
+ protected override void OnCreateClip(TimelineClip clip)
+ {
+ clip.displayName = "Active";
+ base.OnCreateClip(clip);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs.meta
new file mode 100644
index 0000000..82ab218
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Activation/ActivationTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 21bf7f712d84d26478ebe6a299f21738
+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/Animation.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation.meta
new file mode 100644
index 0000000..7fa19e2
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: de9eb5e2046ffc9448f07e495c436506
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs
new file mode 100644
index 0000000..ae190e3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using UnityEngine.Animations;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ // Does a post processing of the weights on an animation track to properly normalize
+ // the mixer weights so that blending does not bring default poses and subtracks, layers and
+ // layer graphs blend correctly
+ class AnimationOutputWeightProcessor : ITimelineEvaluateCallback
+ {
+ struct WeightInfo
+ {
+ public Playable mixer;
+ public Playable parentMixer;
+ public int port;
+ }
+
+ AnimationPlayableOutput m_Output;
+ AnimationMotionXToDeltaPlayable m_MotionXPlayable;
+ readonly List<WeightInfo> m_Mixers = new List<WeightInfo>();
+
+ public AnimationOutputWeightProcessor(AnimationPlayableOutput output)
+ {
+ m_Output = output;
+ output.SetWeight(0);
+ FindMixers();
+ }
+
+ void FindMixers()
+ {
+ var playable = m_Output.GetSourcePlayable();
+ var outputPort = m_Output.GetSourceOutputPort();
+
+ m_Mixers.Clear();
+ // only write the final output in playmode. it should always be 1 in editor because we blend to the defaults
+ FindMixers(playable, outputPort, playable.GetInput(outputPort));
+ }
+
+ // Recursively accumulates mixers.
+ void FindMixers(Playable parent, int port, Playable node)
+ {
+ if (!node.IsValid())
+ return;
+
+ var type = node.GetPlayableType();
+ if (type == typeof(AnimationMixerPlayable) || type == typeof(AnimationLayerMixerPlayable))
+ {
+ // use post fix traversal so children come before parents
+ int subCount = node.GetInputCount();
+ for (int j = 0; j < subCount; j++)
+ {
+ FindMixers(node, j, node.GetInput(j));
+ }
+
+ // if we encounter a layer mixer, we assume there is nesting occuring
+ // and we modulate the weight instead of overwriting it.
+ var weightInfo = new WeightInfo
+ {
+ parentMixer = parent,
+ mixer = node,
+ port = port,
+ };
+ m_Mixers.Add(weightInfo);
+ }
+ else
+ {
+ var count = node.GetInputCount();
+ for (var i = 0; i < count; i++)
+ {
+ FindMixers(parent, port, node.GetInput(i));
+ }
+ }
+ }
+
+ public void Evaluate()
+ {
+ float weight = 1;
+ m_Output.SetWeight(1);
+ for (int i = 0; i < m_Mixers.Count; i++)
+ {
+ var mixInfo = m_Mixers[i];
+ weight = WeightUtility.NormalizeMixer(mixInfo.mixer);
+ mixInfo.parentMixer.SetInputWeight(mixInfo.port, weight);
+ }
+
+ // only write the final weight in player/playmode. In editor, we are blending to the appropriate defaults
+ // the last mixer in the list is the final blend, since the list is composed post-order.
+ if (Application.isPlaying)
+ m_Output.SetWeight(weight);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs.meta
new file mode 100644
index 0000000..c487e39
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationOutputWeightProcessor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a429b38ee9d48c7408c8870baf406034
+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/Animation/AnimationPlayableAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs
new file mode 100644
index 0000000..68355c0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs
@@ -0,0 +1,326 @@
+using System.Collections.Generic;
+using UnityEngine.Animations;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A Playable Asset that represents a single AnimationClip clip.
+ /// </summary>
+ [System.Serializable, NotKeyable]
+ public partial class AnimationPlayableAsset : PlayableAsset, ITimelineClipAsset, IPropertyPreview
+ {
+ /// <summary>
+ /// Whether the source AnimationClip loops during playback.
+ /// </summary>
+ public enum LoopMode
+ {
+ /// <summary>
+ /// Use the loop time setting from the source AnimationClip.
+ /// </summary>
+ [Tooltip("Use the loop time setting from the source AnimationClip.")]
+ UseSourceAsset = 0,
+
+ /// <summary>
+ /// The source AnimationClip loops during playback.
+ /// </summary>
+ [Tooltip("The source AnimationClip loops during playback.")]
+ On = 1,
+
+ /// <summary>
+ /// The source AnimationClip does not loop during playback.
+ /// </summary>
+ [Tooltip("The source AnimationClip does not loop during playback.")]
+ Off = 2
+ }
+
+
+ [SerializeField] private AnimationClip m_Clip;
+ [SerializeField] private Vector3 m_Position = Vector3.zero;
+ [SerializeField] private Vector3 m_EulerAngles = Vector3.zero;
+ [SerializeField] private bool m_UseTrackMatchFields = true;
+ [SerializeField] private MatchTargetFields m_MatchTargetFields = MatchTargetFieldConstants.All;
+ [SerializeField] private bool m_RemoveStartOffset = true; // set by animation track prior to compilation
+ [SerializeField] private bool m_ApplyFootIK = true;
+ [SerializeField] private LoopMode m_Loop = LoopMode.UseSourceAsset;
+
+
+#if UNITY_EDITOR
+ private AnimationOffsetPlayable m_AnimationOffsetPlayable;
+#endif
+
+ /// <summary>
+ /// The translational offset of the clip
+ /// </summary>
+ public Vector3 position
+ {
+ get
+ {
+ return m_Position;
+ }
+ set
+ {
+ m_Position = value;
+#if UNITY_EDITOR
+ if (m_AnimationOffsetPlayable.IsValid())
+ m_AnimationOffsetPlayable.SetPosition(position);
+#endif
+ }
+ }
+
+ /// <summary>
+ /// The rotational offset of the clip, expressed as a Quaternion
+ /// </summary>
+ public Quaternion rotation
+ {
+ get
+ {
+ return Quaternion.Euler(m_EulerAngles);
+ }
+
+ set
+ {
+ m_EulerAngles = value.eulerAngles;
+#if UNITY_EDITOR
+ if (m_AnimationOffsetPlayable.IsValid())
+ m_AnimationOffsetPlayable.SetRotation(value);
+#endif
+ }
+ }
+
+ /// <summary>
+ /// The rotational offset of the clip, expressed in Euler angles
+ /// </summary>
+ public Vector3 eulerAngles
+ {
+ get { return m_EulerAngles; }
+ set
+ {
+ m_EulerAngles = value;
+#if UNITY_EDITOR
+ if (m_AnimationOffsetPlayable.IsValid())
+ m_AnimationOffsetPlayable.SetRotation(rotation);
+#endif
+ }
+ }
+
+ /// <summary>
+ /// Specifies whether to use offset matching options as defined by the track.
+ /// </summary>
+ public bool useTrackMatchFields
+ {
+ get { return m_UseTrackMatchFields; }
+ set { m_UseTrackMatchFields = value; }
+ }
+
+ /// <summary>
+ /// Specifies which fields should be matched when aligning offsets.
+ /// </summary>
+ public MatchTargetFields matchTargetFields
+ {
+ get { return m_MatchTargetFields; }
+ set { m_MatchTargetFields = value; }
+ }
+
+ /// <summary>
+ /// Whether to make the animation clip play relative to its first keyframe.
+ /// </summary>
+ /// <remarks>
+ /// This option only applies to animation clips that animate Transform components.
+ /// </remarks>
+ public bool removeStartOffset
+ {
+ get { return m_RemoveStartOffset; }
+ set { m_RemoveStartOffset = value; }
+ }
+
+
+ /// <summary>
+ /// Enable to apply foot IK to the AnimationClip when the target is humanoid.
+ /// </summary>
+ public bool applyFootIK
+ {
+ get { return m_ApplyFootIK; }
+ set { m_ApplyFootIK = value; }
+ }
+
+ /// <summary>
+ /// Whether the source AnimationClip loops during playback
+ /// </summary>
+ public LoopMode loop
+ {
+ get { return m_Loop; }
+ set { m_Loop = value; }
+ }
+
+
+ internal bool hasRootTransforms
+ {
+ get { return m_Clip != null && HasRootTransforms(m_Clip); }
+ }
+
+ // used for legacy 'scene' mode.
+ internal AppliedOffsetMode appliedOffsetMode { get; set; }
+
+
+ /// <summary>
+ /// The source animation clip
+ /// </summary>
+ public AnimationClip clip
+ {
+ get { return m_Clip; }
+ set
+ {
+ if (value != null)
+ name = "AnimationPlayableAsset of " + value.name;
+ m_Clip = value;
+ }
+ }
+
+ /// <summary>
+ /// Returns the duration required to play the animation clip exactly once
+ /// </summary>
+ public override double duration
+ {
+ get
+ {
+ double length = TimeUtility.GetAnimationClipLength(clip);
+ if (length < float.Epsilon)
+ return base.duration;
+ return length;
+ }
+ }
+
+ /// <summary>
+ /// Returns a description of the PlayableOutputs that may be created for this asset.
+ /// </summary>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get { yield return AnimationPlayableBinding.Create(name, this); }
+ }
+
+ /// <summary>
+ /// Creates the root of a Playable subgraph to play the animation clip.
+ /// </summary>
+ /// <param name="graph">PlayableGraph that will own the playable</param>
+ /// <param name="go">The gameobject that triggered the graph build</param>
+ /// <returns>The root playable of the subgraph</returns>
+ public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
+ {
+ Playable root = CreatePlayable(graph, m_Clip, position, eulerAngles, removeStartOffset, appliedOffsetMode, applyFootIK, m_Loop);
+
+#if UNITY_EDITOR
+ m_AnimationOffsetPlayable = AnimationOffsetPlayable.Null;
+ if (root.IsValid() && root.IsPlayableOfType<AnimationOffsetPlayable>())
+ {
+ m_AnimationOffsetPlayable = (AnimationOffsetPlayable)root;
+ }
+
+ LiveLink();
+#endif
+
+ return root;
+ }
+
+ internal static Playable CreatePlayable(PlayableGraph graph, AnimationClip clip, Vector3 positionOffset, Vector3 eulerOffset, bool removeStartOffset, AppliedOffsetMode mode, bool applyFootIK, LoopMode loop)
+ {
+ if (clip == null || clip.legacy)
+ return Playable.Null;
+
+
+ var clipPlayable = AnimationClipPlayable.Create(graph, clip);
+ clipPlayable.SetRemoveStartOffset(removeStartOffset);
+ clipPlayable.SetApplyFootIK(applyFootIK);
+ clipPlayable.SetOverrideLoopTime(loop != LoopMode.UseSourceAsset);
+ clipPlayable.SetLoopTime(loop == LoopMode.On);
+
+ Playable root = clipPlayable;
+
+ if (ShouldApplyScaleRemove(mode))
+ {
+ var removeScale = AnimationRemoveScalePlayable.Create(graph, 1);
+ graph.Connect(root, 0, removeScale, 0);
+ removeScale.SetInputWeight(0, 1.0f);
+ root = removeScale;
+ }
+
+ if (ShouldApplyOffset(mode, clip))
+ {
+ var offsetPlayable = AnimationOffsetPlayable.Create(graph, positionOffset, Quaternion.Euler(eulerOffset), 1);
+ graph.Connect(root, 0, offsetPlayable, 0);
+ offsetPlayable.SetInputWeight(0, 1.0F);
+ root = offsetPlayable;
+ }
+
+ return root;
+ }
+
+ private static bool ShouldApplyOffset(AppliedOffsetMode mode, AnimationClip clip)
+ {
+ if (mode == AppliedOffsetMode.NoRootTransform || mode == AppliedOffsetMode.SceneOffsetLegacy)
+ return false;
+
+ return HasRootTransforms(clip);
+ }
+
+ private static bool ShouldApplyScaleRemove(AppliedOffsetMode mode)
+ {
+ return mode == AppliedOffsetMode.SceneOffsetLegacyEditor || mode == AppliedOffsetMode.SceneOffsetLegacy || mode == AppliedOffsetMode.TransformOffsetLegacy;
+ }
+
+#if UNITY_EDITOR
+ public void LiveLink()
+ {
+ if (m_AnimationOffsetPlayable.IsValid())
+ {
+ m_AnimationOffsetPlayable.SetPosition(position);
+ m_AnimationOffsetPlayable.SetRotation(rotation);
+ }
+ }
+
+#endif
+
+ /// <summary>
+ /// Returns the capabilities of TimelineClips that contain a AnimationPlayableAsset
+ /// </summary>
+ public ClipCaps clipCaps
+ {
+ get
+ {
+ var caps = ClipCaps.All;
+ if (m_Clip == null || (m_Loop == LoopMode.Off) || (m_Loop == LoopMode.UseSourceAsset && !m_Clip.isLooping))
+ caps &= ~ClipCaps.Looping;
+
+ // empty clips don't support clip in. This allows trim operations to simply become
+ // move operations
+ if (m_Clip == null || m_Clip.empty)
+ caps &= ~ClipCaps.ClipIn;
+
+ return caps;
+ }
+ }
+
+ /// <summary>
+ /// Resets the offsets to default values
+ /// </summary>
+ public void ResetOffsets()
+ {
+ position = Vector3.zero;
+ eulerAngles = Vector3.zero;
+ }
+
+ /// <inheritdoc/>
+ public void GatherProperties(PlayableDirector director, IPropertyCollector driver)
+ {
+ driver.AddFromClip(m_Clip);
+ }
+
+ internal static bool HasRootTransforms(AnimationClip clip)
+ {
+ if (clip == null || clip.empty)
+ return false;
+
+ return clip.hasRootMotion || clip.hasGenericRootTransform || clip.hasMotionCurves || clip.hasRootCurves;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs.meta
new file mode 100644
index 0000000..698bcd5
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 030f85c3f73729f4f976f66ffb23b875
+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/Animation/AnimationPreviewUpdateCallback.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs
new file mode 100644
index 0000000..560f900
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs
@@ -0,0 +1,54 @@
+using System.Collections.Generic;
+using UnityEngine.Animations;
+using UnityEngine.Experimental.Animations;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ class AnimationPreviewUpdateCallback : ITimelineEvaluateCallback
+ {
+ AnimationPlayableOutput m_Output;
+ PlayableGraph m_Graph;
+ List<IAnimationWindowPreview> m_PreviewComponents;
+
+ public AnimationPreviewUpdateCallback(AnimationPlayableOutput output)
+ {
+ m_Output = output;
+
+ Playable playable = m_Output.GetSourcePlayable();
+ if (playable.IsValid())
+ {
+ m_Graph = playable.GetGraph();
+ }
+ }
+
+ public void Evaluate()
+ {
+ if (!m_Graph.IsValid())
+ return;
+
+ if (m_PreviewComponents == null)
+ FetchPreviewComponents();
+
+ foreach (var component in m_PreviewComponents)
+ {
+ if (component != null)
+ {
+ component.UpdatePreviewGraph(m_Graph);
+ }
+ }
+ }
+
+ private void FetchPreviewComponents()
+ {
+ m_PreviewComponents = new List<IAnimationWindowPreview>();
+
+ var animator = m_Output.GetTarget();
+ if (animator == null)
+ return;
+
+ var gameObject = animator.gameObject;
+ m_PreviewComponents.AddRange(gameObject.GetComponents<IAnimationWindowPreview>());
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs.meta
new file mode 100644
index 0000000..9d6167b
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPreviewUpdateCallback.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 755e3e942f7784d458bddba421c0bb72
+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/Animation/AnimationTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs
new file mode 100644
index 0000000..21e811d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs
@@ -0,0 +1,971 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Animations;
+using UnityEngine.Experimental.Animations;
+using UnityEngine.Playables;
+using UnityEngine.Serialization;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Flags specifying which offset fields to match
+ /// </summary>
+ [Flags]
+ public enum MatchTargetFields
+ {
+ /// <summary>
+ /// Translation X value
+ /// </summary>
+ PositionX = 1 << 0,
+ /// <summary>
+ /// Translation Y value
+ /// </summary>
+ PositionY = 1 << 1,
+ /// <summary>
+ /// Translation Z value
+ /// </summary>
+ PositionZ = 1 << 2,
+ /// <summary>
+ /// Rotation Euler Angle X value
+ /// </summary>
+ RotationX = 1 << 3,
+ /// <summary>
+ /// Rotation Euler Angle Y value
+ /// </summary>
+ RotationY = 1 << 4,
+ /// <summary>
+ /// Rotation Euler Angle Z value
+ /// </summary>
+ RotationZ = 1 << 5
+ }
+
+ /// <summary>
+ /// Describes what is used to set the starting position and orientation of each Animation Track.
+ /// </summary>
+ /// <remarks>
+ /// By default, each Animation Track uses ApplyTransformOffsets to start from a set position and orientation.
+ /// To offset each Animation Track based on the current position and orientation in the scene, use ApplySceneOffsets.
+ /// </remarks>
+ public enum TrackOffset
+ {
+ /// <summary>
+ /// Use this setting to offset each Animation Track based on a set position and orientation.
+ /// </summary>
+ ApplyTransformOffsets,
+ /// <summary>
+ /// Use this setting to offset each Animation Track based on the current position and orientation in the scene.
+ /// </summary>
+ ApplySceneOffsets,
+ /// <summary>
+ /// Use this setting to offset root transforms based on the state of the animator.
+ /// </summary>
+ /// <remarks>
+ /// Only use this setting to support legacy Animation Tracks. This mode may be deprecated in a future release.
+ ///
+ /// In Auto mode, when the animator bound to the animation track contains an AnimatorController, it offsets all animations similar to ApplySceneOffsets.
+ /// If no controller is assigned, then all offsets are set to start from a fixed position and orientation, similar to ApplyTransformOffsets.
+ /// In Auto mode, in most cases, root transforms are not affected by local scale or Animator.humanScale, unless the animator has an AnimatorController and Animator.applyRootMotion is set to true.
+ /// </remarks>
+ Auto
+ }
+
+
+ // offset mode
+ enum AppliedOffsetMode
+ {
+ NoRootTransform,
+ TransformOffset,
+ SceneOffset,
+ TransformOffsetLegacy,
+ SceneOffsetLegacy,
+ SceneOffsetEditor, // scene offset mode in editor
+ SceneOffsetLegacyEditor,
+ }
+
+
+ // separate from the enum to hide them from UI elements
+ static class MatchTargetFieldConstants
+ {
+ public static MatchTargetFields All = MatchTargetFields.PositionX | MatchTargetFields.PositionY |
+ MatchTargetFields.PositionZ | MatchTargetFields.RotationX |
+ MatchTargetFields.RotationY | MatchTargetFields.RotationZ;
+
+ public static MatchTargetFields None = 0;
+
+ public static MatchTargetFields Position = MatchTargetFields.PositionX | MatchTargetFields.PositionY |
+ MatchTargetFields.PositionZ;
+
+ public static MatchTargetFields Rotation = MatchTargetFields.RotationX | MatchTargetFields.RotationY |
+ MatchTargetFields.RotationZ;
+
+ public static bool HasAny(this MatchTargetFields me, MatchTargetFields fields)
+ {
+ return (me & fields) != None;
+ }
+
+ public static MatchTargetFields Toggle(this MatchTargetFields me, MatchTargetFields flag)
+ {
+ return me ^ flag;
+ }
+ }
+
+
+ /// <summary>
+ /// A Timeline track used for playing back animations on an Animator.
+ /// </summary>
+ [Serializable]
+ [TrackClipType(typeof(AnimationPlayableAsset), false)]
+ [TrackBindingType(typeof(Animator))]
+ [ExcludeFromPreset]
+ public partial class AnimationTrack : TrackAsset, ILayerable
+ {
+ const string k_DefaultInfiniteClipName = "Recorded";
+ const string k_DefaultRecordableClipName = "Recorded";
+
+ [SerializeField, FormerlySerializedAs("m_OpenClipPreExtrapolation")]
+ TimelineClip.ClipExtrapolation m_InfiniteClipPreExtrapolation = TimelineClip.ClipExtrapolation.None;
+
+ [SerializeField, FormerlySerializedAs("m_OpenClipPostExtrapolation")]
+ TimelineClip.ClipExtrapolation m_InfiniteClipPostExtrapolation = TimelineClip.ClipExtrapolation.None;
+
+ [SerializeField, FormerlySerializedAs("m_OpenClipOffsetPosition")]
+ Vector3 m_InfiniteClipOffsetPosition = Vector3.zero;
+
+ [SerializeField, FormerlySerializedAs("m_OpenClipOffsetEulerAngles")]
+ Vector3 m_InfiniteClipOffsetEulerAngles = Vector3.zero;
+
+ [SerializeField, FormerlySerializedAs("m_OpenClipTimeOffset")]
+ double m_InfiniteClipTimeOffset;
+
+ [SerializeField, FormerlySerializedAs("m_OpenClipRemoveOffset")]
+ bool m_InfiniteClipRemoveOffset; // cached value for remove offset
+
+ [SerializeField]
+ bool m_InfiniteClipApplyFootIK = true;
+
+ [SerializeField, HideInInspector]
+ AnimationPlayableAsset.LoopMode mInfiniteClipLoop = AnimationPlayableAsset.LoopMode.UseSourceAsset;
+
+ [SerializeField]
+ MatchTargetFields m_MatchTargetFields = MatchTargetFieldConstants.All;
+ [SerializeField]
+ Vector3 m_Position = Vector3.zero;
+ [SerializeField]
+ Vector3 m_EulerAngles = Vector3.zero;
+
+
+ [SerializeField] AvatarMask m_AvatarMask;
+ [SerializeField] bool m_ApplyAvatarMask = true;
+
+ [SerializeField] TrackOffset m_TrackOffset = TrackOffset.ApplyTransformOffsets;
+
+ [SerializeField, HideInInspector] AnimationClip m_InfiniteClip;
+
+
+#if UNITY_EDITOR
+ private AnimationClip m_DefaultPoseClip;
+ private AnimationClip m_CachedPropertiesClip;
+
+ AnimationOffsetPlayable m_ClipOffset;
+
+ private Vector3 m_SceneOffsetPosition = Vector3.zero;
+ private Vector3 m_SceneOffsetRotation = Vector3.zero;
+
+ private bool m_HasPreviewComponents = false;
+#endif
+
+ /// <summary>
+ /// The translation offset of the entire track.
+ /// </summary>
+ public Vector3 position
+ {
+ get { return m_Position; }
+ set { m_Position = value; }
+ }
+
+ /// <summary>
+ /// The rotation offset of the entire track, expressed as a quaternion.
+ /// </summary>
+ public Quaternion rotation
+ {
+ get { return Quaternion.Euler(m_EulerAngles); }
+ set { m_EulerAngles = value.eulerAngles; }
+ }
+
+ /// <summary>
+ /// The euler angle representation of the rotation offset of the entire track.
+ /// </summary>
+ public Vector3 eulerAngles
+ {
+ get { return m_EulerAngles; }
+ set { m_EulerAngles = value; }
+ }
+
+ /// <summary>
+ /// Specifies whether to apply track offsets to all clips on the track.
+ /// </summary>
+ /// <remarks>
+ /// This can be used to offset all clips on a track, in addition to the clips individual offsets.
+ /// </remarks>
+ [Obsolete("applyOffset is deprecated. Use trackOffset instead", true)]
+ public bool applyOffsets
+ {
+ get { return false; }
+ set {}
+ }
+
+ /// <summary>
+ /// Specifies what is used to set the starting position and orientation of an Animation Track.
+ /// </summary>
+ /// <remarks>
+ /// Track Offset is only applied when the Animation Track contains animation that modifies the root Transform.
+ /// </remarks>
+ public TrackOffset trackOffset
+ {
+ get { return m_TrackOffset; }
+ set { m_TrackOffset = value; }
+ }
+
+ /// <summary>
+ /// Specifies which fields to match when aligning offsets of clips.
+ /// </summary>
+ public MatchTargetFields matchTargetFields
+ {
+ get { return m_MatchTargetFields; }
+ set { m_MatchTargetFields = value & MatchTargetFieldConstants.All; }
+ }
+
+ /// <summary>
+ /// An AnimationClip storing the data for an infinite track.
+ /// </summary>
+ /// <remarks>
+ /// The value of this property is null when the AnimationTrack is in Clip Mode.
+ /// </remarks>
+ public AnimationClip infiniteClip
+ {
+ get { return m_InfiniteClip; }
+ internal set { m_InfiniteClip = value; }
+ }
+
+ // saved value for converting to/from infinite mode
+ internal bool infiniteClipRemoveOffset
+ {
+ get { return m_InfiniteClipRemoveOffset; }
+ set { m_InfiniteClipRemoveOffset = value; }
+ }
+
+ /// <summary>
+ /// Specifies the AvatarMask to be applied to all clips on the track.
+ /// </summary>
+ /// <remarks>
+ /// Applying an AvatarMask to an animation track will allow discarding portions of the animation being applied on the track.
+ /// </remarks>
+ public AvatarMask avatarMask
+ {
+ get { return m_AvatarMask; }
+ set { m_AvatarMask = value; }
+ }
+
+ /// <summary>
+ /// Specifies whether to apply the AvatarMask to the track.
+ /// </summary>
+ public bool applyAvatarMask
+ {
+ get { return m_ApplyAvatarMask; }
+ set { m_ApplyAvatarMask = value; }
+ }
+
+ // is this track compilable
+
+ internal override bool CanCompileClips()
+ {
+ return !muted && (m_Clips.Count > 0 || (m_InfiniteClip != null && !m_InfiniteClip.empty));
+ }
+
+ /// <inheritdoc/>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get { yield return AnimationPlayableBinding.Create(name, this); }
+ }
+
+
+ /// <summary>
+ /// Specifies whether the Animation Track has clips, or is in infinite mode.
+ /// </summary>
+ public bool inClipMode
+ {
+ get { return clips != null && clips.Length != 0; }
+ }
+
+ /// <summary>
+ /// The translation offset of a track in infinite mode.
+ /// </summary>
+ public Vector3 infiniteClipOffsetPosition
+ {
+ get { return m_InfiniteClipOffsetPosition; }
+ set { m_InfiniteClipOffsetPosition = value; }
+ }
+
+ /// <summary>
+ /// The rotation offset of a track in infinite mode.
+ /// </summary>
+ public Quaternion infiniteClipOffsetRotation
+ {
+ get { return Quaternion.Euler(m_InfiniteClipOffsetEulerAngles); }
+ set { m_InfiniteClipOffsetEulerAngles = value.eulerAngles; }
+ }
+
+ /// <summary>
+ /// The euler angle representation of the rotation offset of the track when in infinite mode.
+ /// </summary>
+ public Vector3 infiniteClipOffsetEulerAngles
+ {
+ get { return m_InfiniteClipOffsetEulerAngles; }
+ set { m_InfiniteClipOffsetEulerAngles = value; }
+ }
+
+ internal bool infiniteClipApplyFootIK
+ {
+ get { return m_InfiniteClipApplyFootIK; }
+ set { m_InfiniteClipApplyFootIK = value; }
+ }
+
+ internal double infiniteClipTimeOffset
+ {
+ get { return m_InfiniteClipTimeOffset; }
+ set { m_InfiniteClipTimeOffset = value; }
+ }
+
+ /// <summary>
+ /// The saved state of pre-extrapolation for clips converted to infinite mode.
+ /// </summary>
+ public TimelineClip.ClipExtrapolation infiniteClipPreExtrapolation
+ {
+ get { return m_InfiniteClipPreExtrapolation; }
+ set { m_InfiniteClipPreExtrapolation = value; }
+ }
+
+ /// <summary>
+ /// The saved state of post-extrapolation for clips when converted to infinite mode.
+ /// </summary>
+ public TimelineClip.ClipExtrapolation infiniteClipPostExtrapolation
+ {
+ get { return m_InfiniteClipPostExtrapolation; }
+ set { m_InfiniteClipPostExtrapolation = value; }
+ }
+
+ /// <summary>
+ /// The saved state of animation clip loop state when converted to infinite mode
+ /// </summary>
+ internal AnimationPlayableAsset.LoopMode infiniteClipLoop
+ {
+ get { return mInfiniteClipLoop; }
+ set { mInfiniteClipLoop = value; }
+ }
+
+ [ContextMenu("Reset Offsets")]
+ void ResetOffsets()
+ {
+ m_Position = Vector3.zero;
+ m_EulerAngles = Vector3.zero;
+ UpdateClipOffsets();
+ }
+
+ /// <summary>
+ /// Creates a TimelineClip on this track that uses an AnimationClip.
+ /// </summary>
+ /// <param name="clip">Source animation clip of the resulting TimelineClip.</param>
+ /// <returns>A new TimelineClip which has an AnimationPlayableAsset asset attached.</returns>
+ public TimelineClip CreateClip(AnimationClip clip)
+ {
+ if (clip == null)
+ return null;
+
+ var newClip = CreateClip<AnimationPlayableAsset>();
+ AssignAnimationClip(newClip, clip);
+ return newClip;
+ }
+
+ /// <summary>
+ /// Creates an AnimationClip that stores the data for an infinite track.
+ /// </summary>
+ /// <remarks>
+ /// If an infiniteClip already exists, this method produces no result, even if you provide a different value
+ /// for infiniteClipName.
+ /// </remarks>
+ /// <remarks>
+ /// This method can't create an infinite clip for an AnimationTrack that contains one or more Timeline clips.
+ /// Use AnimationTrack.inClipMode to determine whether it is possible to create an infinite clip on an AnimationTrack.
+ /// </remarks>
+ /// <remarks>
+ /// When used from the editor, this method attempts to save the created infinite clip to the TimelineAsset.
+ /// The TimelineAsset must already exist in the AssetDatabase to save the infinite clip. If the TimelineAsset
+ /// does not exist, the infinite clip is still created but it is not saved.
+ /// </remarks>
+ /// <param name="infiniteClipName">
+ /// The name of the AnimationClip to create.
+ /// This method does not ensure unique names. If you want a unique clip name, you must provide one.
+ /// See ObjectNames.GetUniqueName for information on a method that creates unique names.
+ /// </param>
+ public void CreateInfiniteClip(string infiniteClipName)
+ {
+ if (inClipMode)
+ {
+ Debug.LogWarning("CreateInfiniteClip cannot create an infinite clip for an AnimationTrack that contains one or more Timeline Clips.");
+ return;
+ }
+
+ if (m_InfiniteClip != null)
+ return;
+
+ m_InfiniteClip = TimelineCreateUtilities.CreateAnimationClipForTrack(string.IsNullOrEmpty(infiniteClipName) ? k_DefaultInfiniteClipName : infiniteClipName, this, false);
+ }
+
+ /// <summary>
+ /// Creates a TimelineClip, AnimationPlayableAsset and an AnimationClip. Use this clip to record in a timeline.
+ /// </summary>
+ /// <remarks>
+ /// When used from the editor, this method attempts to save the created recordable clip to the TimelineAsset.
+ /// The TimelineAsset must already exist in the AssetDatabase to save the recordable clip. If the TimelineAsset
+ /// does not exist, the recordable clip is still created but it is not saved.
+ /// </remarks>
+ /// <param name="animClipName">
+ /// The name of the AnimationClip to create.
+ /// This method does not ensure unique names. If you want a unique clip name, you must provide one.
+ /// See ObjectNames.GetUniqueName for information on a method that creates unique names.
+ /// </param>
+ /// <returns>
+ /// Returns a new TimelineClip with an AnimationPlayableAsset asset attached.
+ /// </returns>
+ public TimelineClip CreateRecordableClip(string animClipName)
+ {
+ var clip = TimelineCreateUtilities.CreateAnimationClipForTrack(string.IsNullOrEmpty(animClipName) ? k_DefaultRecordableClipName : animClipName, this, false);
+
+ var timelineClip = CreateClip(clip);
+ timelineClip.displayName = animClipName;
+ timelineClip.recordable = true;
+ timelineClip.start = 0;
+ timelineClip.duration = 1;
+
+ var apa = timelineClip.asset as AnimationPlayableAsset;
+ if (apa != null)
+ apa.removeStartOffset = false;
+
+ return timelineClip;
+ }
+
+#if UNITY_EDITOR
+ internal Vector3 sceneOffsetPosition
+ {
+ get { return m_SceneOffsetPosition; }
+ set { m_SceneOffsetPosition = value; }
+ }
+
+ internal Vector3 sceneOffsetRotation
+ {
+ get { return m_SceneOffsetRotation; }
+ set { m_SceneOffsetRotation = value; }
+ }
+
+ internal bool hasPreviewComponents
+ {
+ get
+ {
+ if (m_HasPreviewComponents)
+ return true;
+
+ var parentTrack = parent as AnimationTrack;
+ if (parentTrack != null)
+ {
+ return parentTrack.hasPreviewComponents;
+ }
+
+ return false;
+ }
+ }
+#endif
+
+ /// <summary>
+ /// Used to initialize default values on a newly created clip
+ /// </summary>
+ /// <param name="clip">The clip added to the track</param>
+ protected override void OnCreateClip(TimelineClip clip)
+ {
+ var extrapolation = TimelineClip.ClipExtrapolation.None;
+ if (!isSubTrack)
+ extrapolation = TimelineClip.ClipExtrapolation.Hold;
+ clip.preExtrapolationMode = extrapolation;
+ clip.postExtrapolationMode = extrapolation;
+ }
+
+ protected internal override int CalculateItemsHash()
+ {
+ return GetAnimationClipHash(m_InfiniteClip).CombineHash(base.CalculateItemsHash());
+ }
+
+ internal void UpdateClipOffsets()
+ {
+#if UNITY_EDITOR
+ if (m_ClipOffset.IsValid())
+ {
+ m_ClipOffset.SetPosition(position);
+ m_ClipOffset.SetRotation(rotation);
+ }
+#endif
+ }
+
+ Playable CompileTrackPlayable(PlayableGraph graph, TrackAsset track, GameObject go, IntervalTree<RuntimeElement> tree, AppliedOffsetMode mode)
+ {
+ var mixer = AnimationMixerPlayable.Create(graph, track.clips.Length);
+ for (int i = 0; i < track.clips.Length; i++)
+ {
+ var c = track.clips[i];
+ var asset = c.asset as PlayableAsset;
+ if (asset == null)
+ continue;
+
+ var animationAsset = asset as AnimationPlayableAsset;
+ if (animationAsset != null)
+ animationAsset.appliedOffsetMode = mode;
+
+ var source = asset.CreatePlayable(graph, go);
+ if (source.IsValid())
+ {
+ var clip = new RuntimeClip(c, source, mixer);
+ tree.Add(clip);
+ graph.Connect(source, 0, mixer, i);
+ mixer.SetInputWeight(i, 0.0f);
+ }
+ }
+
+ return ApplyTrackOffset(graph, mixer, go, mode);
+ }
+
+ Playable ILayerable.CreateLayerMixer(PlayableGraph graph, GameObject go, int inputCount)
+ {
+ return Playable.Null;
+ }
+
+ internal override Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree<RuntimeElement> tree)
+ {
+ if (isSubTrack)
+ throw new InvalidOperationException("Nested animation tracks should never be asked to create a graph directly");
+
+ List<AnimationTrack> flattenTracks = new List<AnimationTrack>();
+ if (CanCompileClips())
+ flattenTracks.Add(this);
+
+
+ bool animatesRootTransform = AnimatesRootTransform();
+ foreach (var subTrack in GetChildTracks())
+ {
+ var child = subTrack as AnimationTrack;
+ if (child != null && child.CanCompileClips())
+ {
+ animatesRootTransform |= child.AnimatesRootTransform();
+ flattenTracks.Add(child);
+ }
+ }
+
+ // figure out which mode to apply
+ AppliedOffsetMode mode = GetOffsetMode(go, animatesRootTransform);
+ var layerMixer = CreateGroupMixer(graph, go, flattenTracks.Count);
+ for (int c = 0; c < flattenTracks.Count; c++)
+ {
+ var compiledTrackPlayable = flattenTracks[c].inClipMode ?
+ CompileTrackPlayable(graph, flattenTracks[c], go, tree, mode) :
+ flattenTracks[c].CreateInfiniteTrackPlayable(graph, go, tree, mode);
+ graph.Connect(compiledTrackPlayable, 0, layerMixer, c);
+ layerMixer.SetInputWeight(c, flattenTracks[c].inClipMode ? 0 : 1);
+ if (flattenTracks[c].applyAvatarMask && flattenTracks[c].avatarMask != null)
+ {
+ layerMixer.SetLayerMaskFromAvatarMask((uint)c, flattenTracks[c].avatarMask);
+ }
+ }
+
+ bool requiresMotionXPlayable = RequiresMotionXPlayable(mode, go);
+
+ Playable mixer = layerMixer;
+ mixer = CreateDefaultBlend(graph, go, mixer, requiresMotionXPlayable);
+
+ // motionX playable not required in scene offset mode, or root transform mode
+ if (requiresMotionXPlayable)
+ {
+ // If we are animating a root transform, add the motionX to delta playable as the root node
+ var motionXToDelta = AnimationMotionXToDeltaPlayable.Create(graph);
+ graph.Connect(mixer, 0, motionXToDelta, 0);
+ motionXToDelta.SetInputWeight(0, 1.0f);
+ motionXToDelta.SetAbsoluteMotion(UsesAbsoluteMotion(mode));
+ mixer = (Playable)motionXToDelta;
+ }
+
+
+#if UNITY_EDITOR
+ if (!Application.isPlaying)
+ {
+ var animator = GetBinding(go != null ? go.GetComponent<PlayableDirector>() : null);
+ if (animator != null)
+ {
+ GameObject targetGO = animator.gameObject;
+ IAnimationWindowPreview[] previewComponents = targetGO.GetComponents<IAnimationWindowPreview>();
+
+ m_HasPreviewComponents = previewComponents.Length > 0;
+ if (m_HasPreviewComponents)
+ {
+ foreach (var component in previewComponents)
+ {
+ mixer = component.BuildPreviewGraph(graph, mixer);
+ }
+ }
+ }
+ }
+#endif
+
+ return mixer;
+ }
+
+ // Creates a layer mixer containing default blends
+ // the base layer is a default clip of all driven properties
+ // the next layer is optionally the desired default pose (in the case of humanoid, the tpose
+ private Playable CreateDefaultBlend(PlayableGraph graph, GameObject go, Playable mixer, bool requireOffset)
+ {
+#if UNITY_EDITOR
+ if (Application.isPlaying)
+ return mixer;
+
+ int inputs = 1 + ((m_CachedPropertiesClip != null) ? 1 : 0) + ((m_DefaultPoseClip != null) ? 1 : 0);
+ if (inputs == 1)
+ return mixer;
+
+ var defaultPoseMixer = AnimationLayerMixerPlayable.Create(graph, inputs);
+
+ int mixerInput = 0;
+ if (m_CachedPropertiesClip)
+ {
+ var cachedPropertiesClip = AnimationClipPlayable.Create(graph, m_CachedPropertiesClip);
+ cachedPropertiesClip.SetApplyFootIK(false);
+ var defaults = (Playable) cachedPropertiesClip;
+ if (requireOffset)
+ defaults = AttachOffsetPlayable(graph, defaults, m_SceneOffsetPosition, Quaternion.Euler(m_SceneOffsetRotation));
+ graph.Connect(defaults, 0, defaultPoseMixer, mixerInput);
+ defaultPoseMixer.SetInputWeight(mixerInput, 1.0f);
+ mixerInput++;
+ }
+
+ if (m_DefaultPoseClip)
+ {
+ var defaultPose = AnimationClipPlayable.Create(graph, m_DefaultPoseClip);
+ defaultPose.SetApplyFootIK(false);
+ var blendDefault = (Playable) defaultPose;
+ if (requireOffset)
+ blendDefault = AttachOffsetPlayable(graph, blendDefault, m_SceneOffsetPosition, Quaternion.Euler(m_SceneOffsetRotation));
+
+ graph.Connect(blendDefault, 0, defaultPoseMixer, mixerInput);
+ defaultPoseMixer.SetInputWeight(mixerInput, 1.0f);
+ mixerInput++;
+ }
+
+
+ graph.Connect(mixer, 0, defaultPoseMixer, mixerInput);
+ defaultPoseMixer.SetInputWeight(mixerInput, 1.0f);
+
+ return defaultPoseMixer;
+#else
+ return mixer;
+#endif
+ }
+
+ private Playable AttachOffsetPlayable(PlayableGraph graph, Playable playable, Vector3 pos, Quaternion rot)
+ {
+ var offsetPlayable = AnimationOffsetPlayable.Create(graph, pos, rot, 1);
+ offsetPlayable.SetInputWeight(0, 1.0f);
+ graph.Connect(playable, 0, offsetPlayable, 0);
+ return offsetPlayable;
+ }
+
+#if UNITY_EDITOR
+ private static string k_DefaultHumanoidClipPath = "Packages/com.unity.timeline/Editor/StyleSheets/res/HumanoidDefault.anim";
+ private static AnimationClip s_DefaultHumanoidClip = null;
+
+ AnimationClip GetDefaultHumanoidClip()
+ {
+ if (s_DefaultHumanoidClip == null)
+ {
+ s_DefaultHumanoidClip = EditorGUIUtility.LoadRequired(k_DefaultHumanoidClipPath) as AnimationClip;
+ if (s_DefaultHumanoidClip == null)
+ Debug.LogError("Could not load default humanoid animation clip for Timeline");
+ }
+
+ return s_DefaultHumanoidClip;
+ }
+
+#endif
+
+ bool RequiresMotionXPlayable(AppliedOffsetMode mode, GameObject gameObject)
+ {
+ if (mode == AppliedOffsetMode.NoRootTransform)
+ return false;
+ if (mode == AppliedOffsetMode.SceneOffsetLegacy)
+ {
+ var animator = GetBinding(gameObject != null ? gameObject.GetComponent<PlayableDirector>() : null);
+ return animator != null && animator.hasRootMotion;
+ }
+ return true;
+ }
+
+ static bool UsesAbsoluteMotion(AppliedOffsetMode mode)
+ {
+#if UNITY_EDITOR
+ // in editor, previewing is always done in absolute motion
+ if (!Application.isPlaying)
+ return true;
+#endif
+ return mode != AppliedOffsetMode.SceneOffset &&
+ mode != AppliedOffsetMode.SceneOffsetLegacy;
+ }
+
+ bool HasController(GameObject gameObject)
+ {
+ var animator = GetBinding(gameObject != null ? gameObject.GetComponent<PlayableDirector>() : null);
+
+ return animator != null && animator.runtimeAnimatorController != null;
+ }
+
+ internal Animator GetBinding(PlayableDirector director)
+ {
+ if (director == null)
+ return null;
+
+ UnityEngine.Object key = this;
+ if (isSubTrack)
+ key = parent;
+
+ UnityEngine.Object binding = null;
+ if (director != null)
+ binding = director.GetGenericBinding(key);
+
+ Animator animator = null;
+ if (binding != null) // the binding can be an animator or game object
+ {
+ animator = binding as Animator;
+ var gameObject = binding as GameObject;
+ if (animator == null && gameObject != null)
+ animator = gameObject.GetComponent<Animator>();
+ }
+
+ return animator;
+ }
+
+ static AnimationLayerMixerPlayable CreateGroupMixer(PlayableGraph graph, GameObject go, int inputCount)
+ {
+ return AnimationLayerMixerPlayable.Create(graph, inputCount);
+ }
+
+ Playable CreateInfiniteTrackPlayable(PlayableGraph graph, GameObject go, IntervalTree<RuntimeElement> tree, AppliedOffsetMode mode)
+ {
+ if (m_InfiniteClip == null)
+ return Playable.Null;
+
+ var mixer = AnimationMixerPlayable.Create(graph, 1);
+
+ // In infinite mode, we always force the loop mode of the clip off because the clip keys are offset in infinite mode
+ // which causes loop to behave different.
+ // The inline curve editor never shows loops in infinite mode.
+ var playable = AnimationPlayableAsset.CreatePlayable(graph, m_InfiniteClip, m_InfiniteClipOffsetPosition, m_InfiniteClipOffsetEulerAngles, false, mode, infiniteClipApplyFootIK, AnimationPlayableAsset.LoopMode.Off);
+ if (playable.IsValid())
+ {
+ tree.Add(new InfiniteRuntimeClip(playable));
+ graph.Connect(playable, 0, mixer, 0);
+ mixer.SetInputWeight(0, 1.0f);
+ }
+
+ return ApplyTrackOffset(graph, mixer, go, mode);
+ }
+
+ Playable ApplyTrackOffset(PlayableGraph graph, Playable root, GameObject go, AppliedOffsetMode mode)
+ {
+#if UNITY_EDITOR
+ m_ClipOffset = AnimationOffsetPlayable.Null;
+#endif
+
+ // offsets don't apply in scene offset, or if there is no root transform (globally or on this track)
+ if (mode == AppliedOffsetMode.SceneOffsetLegacy ||
+ mode == AppliedOffsetMode.SceneOffset ||
+ mode == AppliedOffsetMode.NoRootTransform ||
+ !AnimatesRootTransform()
+ )
+ return root;
+
+
+ var pos = position;
+ var rot = rotation;
+
+#if UNITY_EDITOR
+ // in the editor use the preview position to playback from if available
+ if (mode == AppliedOffsetMode.SceneOffsetEditor)
+ {
+ pos = m_SceneOffsetPosition;
+ rot = Quaternion.Euler(m_SceneOffsetRotation);
+ }
+#endif
+
+ var offsetPlayable = AnimationOffsetPlayable.Create(graph, pos, rot, 1);
+#if UNITY_EDITOR
+ m_ClipOffset = offsetPlayable;
+#endif
+ graph.Connect(root, 0, offsetPlayable, 0);
+ offsetPlayable.SetInputWeight(0, 1);
+
+ return offsetPlayable;
+ }
+
+ // the evaluation time is large so that the properties always get evaluated
+ internal override void GetEvaluationTime(out double outStart, out double outDuration)
+ {
+ if (inClipMode)
+ {
+ base.GetEvaluationTime(out outStart, out outDuration);
+ }
+ else
+ {
+ outStart = 0;
+ outDuration = TimelineClip.kMaxTimeValue;
+ }
+ }
+
+ internal override void GetSequenceTime(out double outStart, out double outDuration)
+ {
+ if (inClipMode)
+ {
+ base.GetSequenceTime(out outStart, out outDuration);
+ }
+ else
+ {
+ outStart = 0;
+ outDuration = Math.Max(GetNotificationDuration(), TimeUtility.GetAnimationClipLength(m_InfiniteClip));
+ }
+ }
+
+ void AssignAnimationClip(TimelineClip clip, AnimationClip animClip)
+ {
+ if (clip == null || animClip == null)
+ return;
+
+ if (animClip.legacy)
+ throw new InvalidOperationException("Legacy Animation Clips are not supported");
+
+ AnimationPlayableAsset asset = clip.asset as AnimationPlayableAsset;
+ if (asset != null)
+ {
+ asset.clip = animClip;
+ asset.name = animClip.name;
+ var duration = asset.duration;
+ if (!double.IsInfinity(duration) && duration >= TimelineClip.kMinDuration && duration < TimelineClip.kMaxTimeValue)
+ clip.duration = duration;
+ }
+ clip.displayName = animClip.name;
+ }
+
+ /// <summary>
+ /// Called by the Timeline Editor to gather properties requiring preview.
+ /// </summary>
+ /// <param name="director">The PlayableDirector invoking the preview</param>
+ /// <param name="driver">PropertyCollector used to gather previewable properties</param>
+ public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
+ {
+#if UNITY_EDITOR
+ m_SceneOffsetPosition = Vector3.zero;
+ m_SceneOffsetRotation = Vector3.zero;
+
+ var animator = GetBinding(director);
+ if (animator == null)
+ return;
+
+ var animClips = new List<AnimationClip>(this.clips.Length + 2);
+ GetAnimationClips(animClips);
+
+ var hasHumanMotion = animClips.Exists(clip => clip.humanMotion);
+
+ m_SceneOffsetPosition = animator.transform.localPosition;
+ m_SceneOffsetRotation = animator.transform.localEulerAngles;
+
+ // Create default pose clip from collected properties
+ if (hasHumanMotion)
+ animClips.Add(GetDefaultHumanoidClip());
+
+ var bindings = AnimationPreviewUtilities.GetBindings(animator.gameObject, animClips);
+
+ m_CachedPropertiesClip = AnimationPreviewUtilities.CreateDefaultClip(animator.gameObject, bindings);
+ AnimationPreviewUtilities.PreviewFromCurves(animator.gameObject, bindings); // faster to preview from curves then an animation clip
+ m_DefaultPoseClip = hasHumanMotion ? GetDefaultHumanoidClip() : null;
+#endif
+ }
+
+ /// <summary>
+ /// Gather all the animation clips for this track
+ /// </summary>
+ /// <param name="animClips"></param>
+ private void GetAnimationClips(List<AnimationClip> animClips)
+ {
+ foreach (var c in clips)
+ {
+ var a = c.asset as AnimationPlayableAsset;
+ if (a != null && a.clip != null)
+ animClips.Add(a.clip);
+ }
+
+ if (m_InfiniteClip != null)
+ animClips.Add(m_InfiniteClip);
+
+ foreach (var childTrack in GetChildTracks())
+ {
+ var animChildTrack = childTrack as AnimationTrack;
+ if (animChildTrack != null)
+ animChildTrack.GetAnimationClips(animClips);
+ }
+ }
+
+ // calculate which offset mode to apply
+ AppliedOffsetMode GetOffsetMode(GameObject go, bool animatesRootTransform)
+ {
+ if (!animatesRootTransform)
+ return AppliedOffsetMode.NoRootTransform;
+
+ if (m_TrackOffset == TrackOffset.ApplyTransformOffsets)
+ return AppliedOffsetMode.TransformOffset;
+
+ if (m_TrackOffset == TrackOffset.ApplySceneOffsets)
+ return (Application.isPlaying) ? AppliedOffsetMode.SceneOffset : AppliedOffsetMode.SceneOffsetEditor;
+
+ if (HasController(go))
+ {
+ if (!Application.isPlaying)
+ return AppliedOffsetMode.SceneOffsetLegacyEditor;
+ return AppliedOffsetMode.SceneOffsetLegacy;
+ }
+
+ return AppliedOffsetMode.TransformOffsetLegacy;
+ }
+
+ internal bool AnimatesRootTransform()
+ {
+ // infinite mode
+ if (AnimationPlayableAsset.HasRootTransforms(m_InfiniteClip))
+ return true;
+
+ // clip mode
+ foreach (var c in GetClips())
+ {
+ var apa = c.asset as AnimationPlayableAsset;
+ if (apa != null && apa.hasRootTransforms)
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs.meta
new file mode 100644
index 0000000..9ba4e15
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d21dcc2386d650c4597f3633c75a1f98
+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/Animation/ICurvesOwner.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs
new file mode 100644
index 0000000..8d61f57
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs
@@ -0,0 +1,15 @@
+namespace UnityEngine.Timeline
+{
+ interface ICurvesOwner
+ {
+ AnimationClip curves { get; }
+ bool hasCurves { get; }
+ double duration { get; }
+ void CreateCurves(string curvesClipName);
+
+ string defaultCurvesName { get; }
+ Object asset { get; }
+ Object assetOwner { get; }
+ TrackAsset targetTrack { get; }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs.meta
new file mode 100644
index 0000000..d5d95df
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/ICurvesOwner.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 89b31ff5ca0a5eb4797ac65d43949807
+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/AssetUpgrade.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade.meta
new file mode 100644
index 0000000..f5aba63
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0c04c8cb23b78e04492e0f310cdee93e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs
new file mode 100644
index 0000000..5ba31f6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs
@@ -0,0 +1,47 @@
+using System;
+
+namespace UnityEngine.Timeline
+{
+ partial class AnimationPlayableAsset : ISerializationCallbackReceiver
+ {
+ enum Versions
+ {
+ Initial = 0,
+ RotationAsEuler = 1,
+ }
+ static readonly int k_LatestVersion = (int)Versions.RotationAsEuler;
+ [SerializeField, HideInInspector] int m_Version;
+
+ [SerializeField, Obsolete("Use m_RotationEuler Instead", false), HideInInspector]
+ private Quaternion m_Rotation = Quaternion.identity; // deprecated. now saves in euler angles
+
+ void ISerializationCallbackReceiver.OnBeforeSerialize()
+ {
+ m_Version = k_LatestVersion;
+ }
+
+ void ISerializationCallbackReceiver.OnAfterDeserialize()
+ {
+ if (m_Version < k_LatestVersion)
+ {
+ OnUpgradeFromVersion(m_Version); //upgrade derived classes
+ }
+ }
+
+ void OnUpgradeFromVersion(int oldVersion)
+ {
+ if (oldVersion < (int)Versions.RotationAsEuler)
+ AnimationPlayableAssetUpgrade.ConvertRotationToEuler(this);
+ }
+
+ static class AnimationPlayableAssetUpgrade
+ {
+ public static void ConvertRotationToEuler(AnimationPlayableAsset asset)
+ {
+#pragma warning disable 618
+ asset.m_EulerAngles = asset.m_Rotation.eulerAngles;
+#pragma warning restore 618
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs.meta
new file mode 100644
index 0000000..867be5e
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationPlayableAssetUpgrade.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6773203120b27984d9a8572fa3564f03
+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/AssetUpgrade/AnimationTrackUpgrade.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs
new file mode 100644
index 0000000..94c5634
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs
@@ -0,0 +1,102 @@
+using System;
+using System.ComponentModel;
+
+namespace UnityEngine.Timeline
+{
+ partial class AnimationTrack
+ {
+ // 649 is value is only assigned to. they can be updated from old files being serialized
+ #pragma warning disable 649
+ //fields that are used for upgrading should be put here, ideally as read-only
+ [SerializeField, Obsolete("Use m_InfiniteClipOffsetEulerAngles Instead", false), HideInInspector]
+ Quaternion m_OpenClipOffsetRotation = Quaternion.identity;
+
+ [SerializeField, Obsolete("Use m_RotationEuler Instead", false), HideInInspector]
+ Quaternion m_Rotation = Quaternion.identity;
+
+ [SerializeField, Obsolete("Use m_RootTransformOffsetMode", false), HideInInspector]
+ bool m_ApplyOffsets;
+ #pragma warning restore 649
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("openClipOffsetPosition has been deprecated. Use infiniteClipOffsetPosition instead. (UnityUpgradable) -> infiniteClipOffsetPosition", true)]
+ public Vector3 openClipOffsetPosition
+ {
+ get { return infiniteClipOffsetPosition; }
+ set { infiniteClipOffsetPosition = value; }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("openClipOffsetRotation has been deprecated. Use infiniteClipOffsetRotation instead. (UnityUpgradable) -> infiniteClipOffsetRotation", true)]
+ public Quaternion openClipOffsetRotation
+ {
+ get { return infiniteClipOffsetRotation; }
+ set { infiniteClipOffsetRotation = value; }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("openClipOffsetEulerAngles has been deprecated. Use infiniteClipOffsetEulerAngles instead. (UnityUpgradable) -> infiniteClipOffsetEulerAngles", true)]
+ public Vector3 openClipOffsetEulerAngles
+ {
+ get { return infiniteClipOffsetEulerAngles; }
+ set { infiniteClipOffsetEulerAngles = value; }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("openClipPreExtrapolation has been deprecated. Use infiniteClipPreExtrapolation instead. (UnityUpgradable) -> infiniteClipPreExtrapolation", true)]
+ public TimelineClip.ClipExtrapolation openClipPreExtrapolation
+ {
+ get { return infiniteClipPreExtrapolation; }
+ set { infiniteClipPreExtrapolation = value; }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [Obsolete("openClipPostExtrapolation has been deprecated. Use infiniteClipPostExtrapolation instead. (UnityUpgradable) -> infiniteClipPostExtrapolation", true)]
+ public TimelineClip.ClipExtrapolation openClipPostExtrapolation
+ {
+ get { return infiniteClipPostExtrapolation; }
+ set { infiniteClipPostExtrapolation = value; }
+ }
+
+ internal override void OnUpgradeFromVersion(int oldVersion)
+ {
+ if (oldVersion < (int)Versions.RotationAsEuler)
+ AnimationTrackUpgrade.ConvertRotationsToEuler(this);
+ if (oldVersion < (int)Versions.RootMotionUpgrade)
+ AnimationTrackUpgrade.ConvertRootMotion(this);
+ if (oldVersion < (int)Versions.AnimatedTrackProperties)
+ AnimationTrackUpgrade.ConvertInfiniteTrack(this);
+ }
+
+// 612 is Property is Obsolete
+// 618 is Field is Obsolete
+#pragma warning disable 612, 618
+ static class AnimationTrackUpgrade
+ {
+ public static void ConvertRotationsToEuler(AnimationTrack track)
+ {
+ track.m_EulerAngles = track.m_Rotation.eulerAngles;
+ track.m_InfiniteClipOffsetEulerAngles = track.m_OpenClipOffsetRotation.eulerAngles;
+ }
+
+ public static void ConvertRootMotion(AnimationTrack track)
+ {
+ track.m_TrackOffset = TrackOffset.Auto; // loaded tracks should use legacy mode
+
+ // reset offsets if not applied
+ if (!track.m_ApplyOffsets)
+ {
+ track.m_Position = Vector3.zero;
+ track.m_EulerAngles = Vector3.zero;
+ }
+ }
+
+ public static void ConvertInfiniteTrack(AnimationTrack track)
+ {
+ track.m_InfiniteClip = track.m_AnimClip;
+ track.m_AnimClip = null;
+ }
+ }
+#pragma warning restore 612, 618
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs.meta
new file mode 100644
index 0000000..01b86a7
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/AnimationTrackUpgrade.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3b0c53b13a1539949b3b212e049151d1
+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/AssetUpgrade/ClipUpgrade.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs
new file mode 100644
index 0000000..20f3dfd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs
@@ -0,0 +1,34 @@
+namespace UnityEngine.Timeline
+{
+ partial class TimelineClip
+ {
+ enum Versions
+ {
+ Initial = 0,
+ ClipInFromGlobalToLocal = 1
+ }
+ const int k_LatestVersion = (int)Versions.ClipInFromGlobalToLocal;
+ [SerializeField, HideInInspector] int m_Version;
+
+ //fields that are used for upgrading should be put here, ideally as read-only
+
+ void UpgradeToLatestVersion()
+ {
+ if (m_Version < (int)Versions.ClipInFromGlobalToLocal)
+ {
+ TimelineClipUpgrade.UpgradeClipInFromGlobalToLocal(this);
+ }
+ }
+
+ static class TimelineClipUpgrade
+ {
+ // version 0->1, clipIn move from global to local
+ public static void UpgradeClipInFromGlobalToLocal(TimelineClip clip)
+ {
+ // case 936751 -- clipIn was serialized in global, not local offset
+ if (clip.m_ClipIn > 0 && clip.m_TimeScale > float.Epsilon)
+ clip.m_ClipIn *= clip.m_TimeScale;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs.meta
new file mode 100644
index 0000000..0b27935
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/ClipUpgrade.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6a4f0c91a28ece04198b200dd55145d0
+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/AssetUpgrade/TimelineUpgrade.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs
new file mode 100644
index 0000000..86135c6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs
@@ -0,0 +1,21 @@
+namespace UnityEngine.Timeline
+{
+ partial class TimelineAsset
+ {
+ enum Versions
+ {
+ Initial = 0
+ }
+ const int k_LatestVersion = (int)Versions.Initial;
+ [SerializeField, HideInInspector] int m_Version;
+
+ //fields that are used for upgrading should be put here, ideally as read-only
+
+ void UpgradeToLatestVersion()
+ {}
+
+ //upgrade code should go into this class
+ static class TimelineAssetUpgrade
+ {}
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs.meta
new file mode 100644
index 0000000..6075bab
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TimelineUpgrade.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 95c91abdcc1ea03458c2ea4e9626a5d8
+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/AssetUpgrade/TrackUpgrade.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs
new file mode 100644
index 0000000..6768199
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs
@@ -0,0 +1,76 @@
+using System;
+using UnityEngine.Serialization;
+
+namespace UnityEngine.Timeline
+{
+ partial class TrackAsset : ISerializationCallbackReceiver
+ {
+ internal enum Versions
+ {
+ Initial = 0,
+ RotationAsEuler = 1,
+ RootMotionUpgrade = 2,
+ AnimatedTrackProperties = 3
+ }
+
+ const int k_LatestVersion = (int)Versions.AnimatedTrackProperties;
+
+ [SerializeField, HideInInspector] int m_Version;
+
+ [Obsolete("Please use m_InfiniteClip (on AnimationTrack) instead.", false)]
+ [SerializeField, HideInInspector, FormerlySerializedAs("m_animClip")]
+ internal AnimationClip m_AnimClip;
+
+ protected virtual void OnBeforeTrackSerialize() {}
+ protected virtual void OnAfterTrackDeserialize() {}
+
+ internal virtual void OnUpgradeFromVersion(int oldVersion) {}
+
+ void ISerializationCallbackReceiver.OnBeforeSerialize()
+ {
+ m_Version = k_LatestVersion;
+
+ //make sure children are correctly parented
+ if (m_Children != null)
+ {
+ for (var i = m_Children.Count - 1; i >= 0; i--)
+ {
+ var asset = m_Children[i] as TrackAsset;
+ if (asset != null && asset.parent != this)
+ asset.parent = this;
+ }
+ }
+
+ OnBeforeTrackSerialize();
+ }
+
+ void ISerializationCallbackReceiver.OnAfterDeserialize()
+ {
+ // Clear the clip cache when a deserialize is performed, or
+ // we can get out of sync when performing Undo
+ m_ClipsCache = null;
+ Invalidate();
+
+ if (m_Version < k_LatestVersion)
+ {
+ UpgradeToLatestVersion(); //upgrade TrackAsset
+ OnUpgradeFromVersion(m_Version); //upgrade derived classes
+ }
+
+ foreach (var marker in GetMarkers())
+ {
+ marker.Initialize(this);
+ }
+
+ OnAfterTrackDeserialize();
+ }
+
+ //fields that are used for upgrading should be put here, ideally as read-only
+ void UpgradeToLatestVersion()
+ {}
+
+ //upgrade code should go into this class
+ static class TrackAssetUpgrade
+ {}
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs.meta
new file mode 100644
index 0000000..bbe22f0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/AssetUpgrade/TrackUpgrade.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c68f34993bfe85e489158a29c99a20b5
+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/Attributes.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes.meta
new file mode 100644
index 0000000..d77a179
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ec817e5e5781e0a4983a1dc8875d1974
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs
new file mode 100644
index 0000000..a6abc20
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Attribute used to specify the color of the track and its clips inside the Timeline Editor.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public class TrackColorAttribute : Attribute
+ {
+ Color m_Color;
+
+ /// <summary>
+ ///
+ /// </summary>
+ public Color color
+ {
+ get { return m_Color; }
+ }
+
+ /// <summary>
+ /// Specify the track color using [0-1] R,G,B values.
+ /// </summary>
+ /// <param name="r">Red value [0-1].</param>
+ /// <param name="g">Green value [0-1].</param>
+ /// <param name="b">Blue value [0-1].</param>
+ public TrackColorAttribute(float r, float g, float b)
+ {
+ m_Color = new Color(r, g, b);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs.meta
new file mode 100644
index 0000000..80c61ba
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Attributes/TrackColorAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6c3d52cc5c46d7946a920e21901ff38e
+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/Audio.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio.meta
new file mode 100644
index 0000000..b3fd165
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d19b75372f4e44d4fa4b2cffbb54124b
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs
new file mode 100644
index 0000000..0c5894b
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs
@@ -0,0 +1,13 @@
+using System;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ [Serializable]
+ [NotKeyable]
+ class AudioClipProperties : PlayableBehaviour
+ {
+ [Range(0.0f, 1.0f)]
+ public float volume = 1.0f;
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs.meta
new file mode 100644
index 0000000..a044757
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioClipProperties.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0d60a406ab64c434e9d731914e11a51e
+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/Audio/AudioMixerProperties.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs
new file mode 100644
index 0000000..c5bdf8c
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs
@@ -0,0 +1,45 @@
+using System;
+using UnityEngine.Audio;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ [Serializable]
+ class AudioMixerProperties : PlayableBehaviour
+ {
+ [Range(0.0f, 1.0f)]
+ public float volume = 1.0f;
+
+ [Range(-1.0f, 1.0f)]
+ public float stereoPan = 0.0f;
+
+ [Range(0.0f, 1.0f)]
+ public float spatialBlend = 0.0f;
+
+ public override void PrepareFrame(Playable playable, FrameData info)
+ {
+ if (!playable.IsValid() || !playable.IsPlayableOfType<AudioMixerPlayable>())
+ return;
+
+ var inputCount = playable.GetInputCount();
+
+ for (int i = 0; i < inputCount; ++i)
+ {
+ if (playable.GetInputWeight(i) > 0.0f)
+ {
+ var input = playable.GetInput(i);
+
+ if (input.IsValid() && input.IsPlayableOfType<AudioClipPlayable>())
+ {
+ var audioClipPlayable = (AudioClipPlayable)input;
+ var audioClipProperties = input.GetHandle().GetObject<AudioClipProperties>();
+
+ audioClipPlayable.SetVolume(Mathf.Clamp01(volume * audioClipProperties.volume));
+ audioClipPlayable.SetStereoPan(Mathf.Clamp(stereoPan, -1.0f, 1.0f));
+ audioClipPlayable.SetSpatialBlend(Mathf.Clamp01(spatialBlend));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs.meta
new file mode 100644
index 0000000..fa975ef
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioMixerProperties.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d8c4a920f001ca64680ed6fdb52d1753
+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/Audio/AudioPlayableAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs
new file mode 100644
index 0000000..7ff40fc
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Audio;
+#if UNITY_EDITOR
+using System.ComponentModel;
+#endif
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// PlayableAsset wrapper for an AudioClip in Timeline.
+ /// </summary>
+ [Serializable]
+#if UNITY_EDITOR
+ [DisplayName("Audio Clip")]
+#endif
+ public class AudioPlayableAsset : PlayableAsset, ITimelineClipAsset
+ {
+ [SerializeField] AudioClip m_Clip;
+#pragma warning disable 649 //Field is never assigned to and will always have its default value
+ [SerializeField] bool m_Loop;
+ [SerializeField, HideInInspector] float m_bufferingTime = 0.1f;
+ [SerializeField] AudioClipProperties m_ClipProperties = new AudioClipProperties();
+
+ // the amount of time to give the clip to load prior to it's start time
+ internal float bufferingTime
+ {
+ get { return m_bufferingTime; }
+ set { m_bufferingTime = value; }
+ }
+
+#if UNITY_EDITOR
+ Playable m_LiveClipPlayable = Playable.Null;
+
+#endif
+
+ /// <summary>
+ /// The audio clip to be played
+ /// </summary>
+ public AudioClip clip
+ {
+ get { return m_Clip; }
+ set { m_Clip = value; }
+ }
+
+ /// <summary>
+ /// Whether the audio clip loops.
+ /// </summary>
+ /// <remarks>
+ /// Use this to loop the audio clip when the duration of the timeline clip exceeds that of the audio clip.
+ /// </remarks>
+ public bool loop
+ {
+ get { return m_Loop; }
+ set { m_Loop = value; }
+ }
+
+ /// <summary>
+ /// Returns the duration required to play the audio clip exactly once
+ /// </summary>
+ public override double duration
+ {
+ get
+ {
+ if (m_Clip == null)
+ return base.duration;
+
+ // use this instead of length to avoid rounding precision errors,
+ return (double)m_Clip.samples / m_Clip.frequency;
+ }
+ }
+
+ /// <summary>
+ /// Returns a description of the PlayableOutputs that may be created for this asset.
+ /// </summary>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get { yield return AudioPlayableBinding.Create(name, this); }
+ }
+
+ /// <summary>
+ /// Creates the root of a Playable subgraph to play the audio clip.
+ /// </summary>
+ /// <param name="graph">PlayableGraph that will own the playable</param>
+ /// <param name="go">The GameObject that triggered the graph build</param>
+ /// <returns>The root playable of the subgraph</returns>
+ public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
+ {
+ if (m_Clip == null)
+ return Playable.Null;
+
+ var audioClipPlayable = AudioClipPlayable.Create(graph, m_Clip, m_Loop);
+ audioClipPlayable.GetHandle().SetScriptInstance(m_ClipProperties.Clone());
+
+#if UNITY_EDITOR
+ m_LiveClipPlayable = audioClipPlayable;
+#endif
+
+ return audioClipPlayable;
+ }
+
+ /// <summary>
+ /// Returns the capabilities of TimelineClips that contain an AudioPlayableAsset
+ /// </summary>
+ public ClipCaps clipCaps
+ {
+ get
+ {
+ return ClipCaps.ClipIn |
+ ClipCaps.SpeedMultiplier |
+ ClipCaps.Blending |
+ (m_Loop ? ClipCaps.Looping : ClipCaps.None);
+ }
+ }
+
+#if UNITY_EDITOR
+ internal void LiveLink()
+ {
+ if (!m_LiveClipPlayable.IsValid())
+ return;
+
+ var audioMixerProperties = m_LiveClipPlayable.GetHandle().GetObject<AudioClipProperties>();
+
+ if (audioMixerProperties == null)
+ return;
+
+ audioMixerProperties.volume = m_ClipProperties.volume;
+ }
+
+#endif
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs.meta
new file mode 100644
index 0000000..1b64816
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioPlayableAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4f10dd60657c6004587f237a7e90f8e4
+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/Audio/AudioTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs
new file mode 100644
index 0000000..d35fac6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Audio;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A Timeline track that can play AudioClips.
+ /// </summary>
+ [Serializable]
+ [TrackClipType(typeof(AudioPlayableAsset), false)]
+ [TrackBindingType(typeof(AudioSource))]
+ [ExcludeFromPreset]
+ public class AudioTrack : TrackAsset
+ {
+ [SerializeField]
+ AudioMixerProperties m_TrackProperties = new AudioMixerProperties();
+
+#if UNITY_EDITOR
+ Playable m_LiveMixerPlayable = Playable.Null;
+
+#endif
+
+ /// <summary>
+ /// Create an TimelineClip for playing an AudioClip on this track.
+ /// </summary>
+ /// <param name="clip">The audio clip to play</param>
+ /// <returns>A TimelineClip with an AudioPlayableAsset asset.</returns>
+ public TimelineClip CreateClip(AudioClip clip)
+ {
+ if (clip == null)
+ return null;
+
+ var newClip = CreateDefaultClip();
+
+ var audioAsset = newClip.asset as AudioPlayableAsset;
+ if (audioAsset != null)
+ audioAsset.clip = clip;
+
+ newClip.duration = clip.length;
+ newClip.displayName = clip.name;
+
+ return newClip;
+ }
+
+ internal override Playable CompileClips(PlayableGraph graph, GameObject go, IList<TimelineClip> timelineClips, IntervalTree<RuntimeElement> tree)
+ {
+ var clipBlender = AudioMixerPlayable.Create(graph, timelineClips.Count);
+
+#if UNITY_EDITOR
+ clipBlender.GetHandle().SetScriptInstance(m_TrackProperties.Clone());
+ m_LiveMixerPlayable = clipBlender;
+#else
+ if (hasCurves)
+ clipBlender.GetHandle().SetScriptInstance(m_TrackProperties.Clone());
+#endif
+
+ for (int i = 0; i < timelineClips.Count; i++)
+ {
+ var c = timelineClips[i];
+ var asset = c.asset as PlayableAsset;
+ if (asset == null)
+ continue;
+
+ var buffer = 0.1f;
+ var audioAsset = c.asset as AudioPlayableAsset;
+ if (audioAsset != null)
+ buffer = audioAsset.bufferingTime;
+
+ var source = asset.CreatePlayable(graph, go);
+ if (!source.IsValid())
+ continue;
+
+ if (source.IsPlayableOfType<AudioClipPlayable>())
+ {
+ // Enforce initial values on all clips
+ var audioClipPlayable = (AudioClipPlayable)source;
+ var audioClipProperties = audioClipPlayable.GetHandle().GetObject<AudioClipProperties>();
+
+ audioClipPlayable.SetVolume(Mathf.Clamp01(m_TrackProperties.volume * audioClipProperties.volume));
+ audioClipPlayable.SetStereoPan(Mathf.Clamp(m_TrackProperties.stereoPan, -1.0f, 1.0f));
+ audioClipPlayable.SetSpatialBlend(Mathf.Clamp01(m_TrackProperties.spatialBlend));
+ }
+
+ tree.Add(new ScheduleRuntimeClip(c, source, clipBlender, buffer));
+ graph.Connect(source, 0, clipBlender, i);
+ source.SetSpeed(c.timeScale);
+ source.SetDuration(c.extrapolatedDuration);
+ clipBlender.SetInputWeight(source, 1.0f);
+ }
+
+ ConfigureTrackAnimation(tree, go, clipBlender);
+
+ return clipBlender;
+ }
+
+ /// <inheritdoc/>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get { yield return AudioPlayableBinding.Create(name, this); }
+ }
+
+#if UNITY_EDITOR
+ internal void LiveLink()
+ {
+ if (!m_LiveMixerPlayable.IsValid())
+ return;
+
+ var audioMixerProperties = m_LiveMixerPlayable.GetHandle().GetObject<AudioMixerProperties>();
+
+ if (audioMixerProperties == null)
+ return;
+
+ audioMixerProperties.volume = m_TrackProperties.volume;
+ audioMixerProperties.stereoPan = m_TrackProperties.stereoPan;
+ audioMixerProperties.spatialBlend = m_TrackProperties.spatialBlend;
+ }
+
+#endif
+
+ void OnValidate()
+ {
+ m_TrackProperties.volume = Mathf.Clamp01(m_TrackProperties.volume);
+ m_TrackProperties.stereoPan = Mathf.Clamp(m_TrackProperties.stereoPan, -1.0f, 1.0f);
+ m_TrackProperties.spatialBlend = Mathf.Clamp01(m_TrackProperties.spatialBlend);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs.meta
new file mode 100644
index 0000000..2a826c9
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Audio/AudioTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8b22792c3b570444eb18cb78c2af3a74
+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/ClipCaps.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs
new file mode 100644
index 0000000..2a5efb6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs
@@ -0,0 +1,85 @@
+using System;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Describes the timeline features supported by a clip
+ /// </summary>
+ [Flags]
+ public enum ClipCaps
+ {
+ /// <summary>
+ /// No features are supported.
+ /// </summary>
+ None = 0 ,
+
+ /// <summary>
+ /// The clip supports loops.
+ /// </summary>
+ Looping = 1 << 0,
+
+ /// <summary>
+ /// The clip supports clip extrapolation.
+ /// </summary>
+ Extrapolation = 1 << 1,
+
+ /// <summary>
+ /// The clip supports initial local times greater than zero.
+ /// </summary>
+ ClipIn = 1 << 2,
+
+ /// <summary>
+ /// The clip supports time scaling.
+ /// </summary>
+ SpeedMultiplier = 1 << 3,
+
+ /// <summary>
+ /// The clip supports blending between clips.
+ /// </summary>
+ Blending = 1 << 4,
+
+ /// <summary>
+ /// All features are supported.
+ /// </summary>
+ All = ~None
+ }
+
+ static class TimelineClipCapsExtensions
+ {
+ public static bool SupportsLooping(this TimelineClip clip)
+ {
+ return clip != null && (clip.clipCaps & ClipCaps.Looping) != ClipCaps.None;
+ }
+
+ public static bool SupportsExtrapolation(this TimelineClip clip)
+ {
+ return clip != null && (clip.clipCaps & ClipCaps.Extrapolation) != ClipCaps.None;
+ }
+
+ public static bool SupportsClipIn(this TimelineClip clip)
+ {
+ return clip != null && (clip.clipCaps & ClipCaps.ClipIn) != ClipCaps.None;
+ }
+
+ public static bool SupportsSpeedMultiplier(this TimelineClip clip)
+ {
+ return clip != null && (clip.clipCaps & ClipCaps.SpeedMultiplier) != ClipCaps.None;
+ }
+
+ public static bool SupportsBlending(this TimelineClip clip)
+ {
+ return clip != null && (clip.clipCaps & ClipCaps.Blending) != ClipCaps.None;
+ }
+
+ public static bool HasAll(this ClipCaps caps, ClipCaps flags)
+ {
+ return (caps & flags) == flags;
+ }
+
+ public static bool HasAny(this ClipCaps caps, ClipCaps flags)
+ {
+ return (caps & flags) != 0;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs.meta
new file mode 100644
index 0000000..ba03648
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ClipCaps.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 667a99762bdf5484fbaa02573fd396e2
+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/Control.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control.meta
new file mode 100644
index 0000000..e4a557d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ea998292f45ea494d9e100f5f6362f91
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs
new file mode 100644
index 0000000..fd806f6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs
@@ -0,0 +1,406 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Playable Asset that generates playables for controlling time-related elements on a GameObject.
+ /// </summary>
+ [Serializable]
+ [NotKeyable]
+ public class ControlPlayableAsset : PlayableAsset, IPropertyPreview, ITimelineClipAsset
+ {
+ const int k_MaxRandInt = 10000;
+ static readonly List<PlayableDirector> k_EmptyDirectorsList = new List<PlayableDirector>(0);
+ static readonly List<ParticleSystem> k_EmptyParticlesList = new List<ParticleSystem>(0);
+
+ /// <summary>
+ /// GameObject in the scene to control, or the parent of the instantiated prefab.
+ /// </summary>
+ [SerializeField] public ExposedReference<GameObject> sourceGameObject;
+
+ /// <summary>
+ /// Prefab object that will be instantiated.
+ /// </summary>
+ [SerializeField] public GameObject prefabGameObject;
+
+ /// <summary>
+ /// Indicates whether Particle Systems will be controlled.
+ /// </summary>
+ [SerializeField] public bool updateParticle = true;
+
+ /// <summary>
+ /// Random seed to supply particle systems that are set to use autoRandomSeed
+ /// </summary>
+ /// <remarks>
+ /// This is used to maintain determinism when playing back in timeline. Sub emitters will be assigned incrementing random seeds to maintain determinism and distinction.
+ /// </remarks>
+ [SerializeField] public uint particleRandomSeed;
+
+ /// <summary>
+ /// Indicates whether playableDirectors are controlled.
+ /// </summary>
+ [SerializeField] public bool updateDirector = true;
+
+ /// <summary>
+ /// Indicates whether Monobehaviours implementing ITimeControl will be controlled.
+ /// </summary>
+ [SerializeField] public bool updateITimeControl = true;
+
+ /// <summary>
+ /// Indicates whether to search the entire hierarchy for controllable components.
+ /// </summary>
+ [SerializeField] public bool searchHierarchy = false;
+
+ /// <summary>
+ /// Indicate whether GameObject activation is controlled
+ /// </summary>
+ [SerializeField] public bool active = true;
+
+ /// <summary>
+ /// Indicates the active state of the GameObject when Timeline is stopped.
+ /// </summary>
+ [SerializeField] public ActivationControlPlayable.PostPlaybackState postPlayback = ActivationControlPlayable.PostPlaybackState.Revert;
+
+ PlayableAsset m_ControlDirectorAsset;
+ double m_Duration = PlayableBinding.DefaultDuration;
+ bool m_SupportLoop;
+
+ private static HashSet<PlayableDirector> s_ProcessedDirectors = new HashSet<PlayableDirector>();
+ private static HashSet<GameObject> s_CreatedPrefabs = new HashSet<GameObject>();
+
+ // does the last instance created control directors and/or particles
+ internal bool controllingDirectors { get; private set; }
+ internal bool controllingParticles { get; private set; }
+
+ /// <summary>
+ /// This function is called when the object is loaded.
+ /// </summary>
+ public void OnEnable()
+ {
+ // can't be set in a constructor
+ if (particleRandomSeed == 0)
+ particleRandomSeed = (uint)Random.Range(1, k_MaxRandInt);
+ }
+
+ /// <summary>
+ /// Returns the duration in seconds needed to play the underlying director or particle system exactly once.
+ /// </summary>
+ public override double duration { get { return m_Duration; } }
+
+ /// <summary>
+ /// Returns the capabilities of TimelineClips that contain a ControlPlayableAsset
+ /// </summary>
+ public ClipCaps clipCaps
+ {
+ get { return ClipCaps.ClipIn | ClipCaps.SpeedMultiplier | (m_SupportLoop ? ClipCaps.Looping : ClipCaps.None); }
+ }
+
+ /// <summary>
+ /// Creates the root of a Playable subgraph to control the contents of the game object.
+ /// </summary>
+ /// <param name="graph">PlayableGraph that will own the playable</param>
+ /// <param name="go">The GameObject that triggered the graph build</param>
+ /// <returns>The root playable of the subgraph</returns>
+ public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
+ {
+ // case 989856
+ if (prefabGameObject != null)
+ {
+ if (s_CreatedPrefabs.Contains(prefabGameObject))
+ {
+ Debug.LogWarningFormat("Control Track Clip ({0}) is causing a prefab to instantiate itself recursively. Aborting further instances.", name);
+ return Playable.Create(graph);
+ }
+ s_CreatedPrefabs.Add(prefabGameObject);
+ }
+
+ Playable root = Playable.Null;
+ var playables = new List<Playable>();
+
+ GameObject sourceObject = sourceGameObject.Resolve(graph.GetResolver());
+ if (prefabGameObject != null)
+ {
+ Transform parenTransform = sourceObject != null ? sourceObject.transform : null;
+ var controlPlayable = PrefabControlPlayable.Create(graph, prefabGameObject, parenTransform);
+
+ sourceObject = controlPlayable.GetBehaviour().prefabInstance;
+ playables.Add(controlPlayable);
+ }
+
+ m_Duration = PlayableBinding.DefaultDuration;
+ m_SupportLoop = false;
+
+ controllingParticles = false;
+ controllingDirectors = false;
+
+ if (sourceObject != null)
+ {
+ var directors = updateDirector ? GetComponent<PlayableDirector>(sourceObject) : k_EmptyDirectorsList;
+ var particleSystems = updateParticle ? GetParticleSystemRoots(sourceObject) : k_EmptyParticlesList;
+
+ // update the duration and loop values (used for UI purposes) here
+ // so they are tied to the latest gameObject bound
+ UpdateDurationAndLoopFlag(directors, particleSystems);
+
+ var director = go.GetComponent<PlayableDirector>();
+ if (director != null)
+ m_ControlDirectorAsset = director.playableAsset;
+
+ if (go == sourceObject && prefabGameObject == null)
+ {
+ Debug.LogWarningFormat("Control Playable ({0}) is referencing the same PlayableDirector component than the one in which it is playing.", name);
+ active = false;
+ if (!searchHierarchy)
+ updateDirector = false;
+ }
+
+ if (active)
+ CreateActivationPlayable(sourceObject, graph, playables);
+
+ if (updateDirector)
+ SearchHierarchyAndConnectDirector(directors, graph, playables, prefabGameObject != null);
+
+ if (updateParticle)
+ SearchHiearchyAndConnectParticleSystem(particleSystems, graph, playables);
+
+ if (updateITimeControl)
+ SearchHierarchyAndConnectControlableScripts(GetControlableScripts(sourceObject), graph, playables);
+
+ // Connect Playables to Generic to Mixer
+ root = ConnectPlayablesToMixer(graph, playables);
+ }
+
+ if (prefabGameObject != null)
+ s_CreatedPrefabs.Remove(prefabGameObject);
+
+ if (!root.IsValid())
+ root = Playable.Create(graph);
+
+ return root;
+ }
+
+ static Playable ConnectPlayablesToMixer(PlayableGraph graph, List<Playable> playables)
+ {
+ var mixer = Playable.Create(graph, playables.Count);
+
+ for (int i = 0; i != playables.Count; ++i)
+ {
+ ConnectMixerAndPlayable(graph, mixer, playables[i], i);
+ }
+
+ mixer.SetPropagateSetTime(true);
+
+ return mixer;
+ }
+
+ void CreateActivationPlayable(GameObject root, PlayableGraph graph,
+ List<Playable> outplayables)
+ {
+ var activation = ActivationControlPlayable.Create(graph, root, postPlayback);
+ if (activation.IsValid())
+ outplayables.Add(activation);
+ }
+
+ void SearchHiearchyAndConnectParticleSystem(IEnumerable<ParticleSystem> particleSystems, PlayableGraph graph,
+ List<Playable> outplayables)
+ {
+ foreach (var particleSystem in particleSystems)
+ {
+ if (particleSystem != null)
+ {
+ controllingParticles = true;
+ outplayables.Add(ParticleControlPlayable.Create(graph, particleSystem, particleRandomSeed));
+ }
+ }
+ }
+
+ void SearchHierarchyAndConnectDirector(IEnumerable<PlayableDirector> directors, PlayableGraph graph,
+ List<Playable> outplayables, bool disableSelfReferences)
+ {
+ foreach (var director in directors)
+ {
+ if (director != null)
+ {
+ if (director.playableAsset != m_ControlDirectorAsset)
+ {
+ outplayables.Add(DirectorControlPlayable.Create(graph, director));
+ controllingDirectors = true;
+ }
+ // if this self references, disable the director.
+ else if (disableSelfReferences)
+ {
+ director.enabled = false;
+ }
+ }
+ }
+ }
+
+ static void SearchHierarchyAndConnectControlableScripts(IEnumerable<MonoBehaviour> controlableScripts, PlayableGraph graph, List<Playable> outplayables)
+ {
+ foreach (var script in controlableScripts)
+ {
+ outplayables.Add(TimeControlPlayable.Create(graph, (ITimeControl)script));
+ }
+ }
+
+ static void ConnectMixerAndPlayable(PlayableGraph graph, Playable mixer, Playable playable,
+ int portIndex)
+ {
+ graph.Connect(playable, 0, mixer, portIndex);
+ mixer.SetInputWeight(playable, 1.0f);
+ }
+
+ internal IList<T> GetComponent<T>(GameObject gameObject)
+ {
+ var components = new List<T>();
+ if (gameObject != null)
+ {
+ if (searchHierarchy)
+ {
+ gameObject.GetComponentsInChildren<T>(true, components);
+ }
+ else
+ {
+ gameObject.GetComponents<T>(components);
+ }
+ }
+ return components;
+ }
+
+ static IEnumerable<MonoBehaviour> GetControlableScripts(GameObject root)
+ {
+ if (root == null)
+ yield break;
+
+ foreach (var script in root.GetComponentsInChildren<MonoBehaviour>())
+ {
+ if (script is ITimeControl)
+ yield return script;
+ }
+ }
+
+ internal void UpdateDurationAndLoopFlag(IList<PlayableDirector> directors, IList<ParticleSystem> particleSystems)
+ {
+ if (directors.Count == 0 && particleSystems.Count == 0)
+ return;
+
+ const double invalidDuration = double.NegativeInfinity;
+
+ var maxDuration = invalidDuration;
+ var supportsLoop = false;
+
+ foreach (var director in directors)
+ {
+ if (director.playableAsset != null)
+ {
+ var assetDuration = director.playableAsset.duration;
+
+ if (director.playableAsset is TimelineAsset && assetDuration > 0.0)
+ // Timeline assets report being one tick shorter than they actually are, unless they are empty
+ assetDuration = (double)((DiscreteTime)assetDuration).OneTickAfter();
+
+ maxDuration = Math.Max(maxDuration, assetDuration);
+ supportsLoop = supportsLoop || director.extrapolationMode == DirectorWrapMode.Loop;
+ }
+ }
+
+ foreach (var particleSystem in particleSystems)
+ {
+ maxDuration = Math.Max(maxDuration, particleSystem.main.duration);
+ supportsLoop = supportsLoop || particleSystem.main.loop;
+ }
+
+ m_Duration = double.IsNegativeInfinity(maxDuration) ? PlayableBinding.DefaultDuration : maxDuration;
+ m_SupportLoop = supportsLoop;
+ }
+
+ IList<ParticleSystem> GetParticleSystemRoots(GameObject go)
+ {
+ if (searchHierarchy)
+ {
+ // We only want the parent systems as they will handle all the child systems.
+ var roots = new List<ParticleSystem>();
+ GetParticleSystemRoots(go.transform, roots);
+ return roots;
+ }
+ return GetComponent<ParticleSystem>(go);
+ }
+
+ static void GetParticleSystemRoots(Transform t, ICollection<ParticleSystem> roots)
+ {
+ var ps = t.GetComponent<ParticleSystem>();
+ if (ps != null)
+ {
+ // its a root
+ roots.Add(ps);
+ return;
+ }
+
+ for (int i = 0; i < t.childCount; ++i)
+ {
+ GetParticleSystemRoots(t.GetChild(i), roots);
+ }
+ }
+
+ /// <inheritdoc/>
+ public void GatherProperties(PlayableDirector director, IPropertyCollector driver)
+ {
+ if (director == null)
+ return;
+
+ // prevent infinite recursion
+ if (s_ProcessedDirectors.Contains(director))
+ return;
+ s_ProcessedDirectors.Add(director);
+
+ var gameObject = sourceGameObject.Resolve(director);
+ if (gameObject != null)
+ {
+ if (updateParticle)
+ {
+ // case 1076850 -- drive all emitters, not just roots.
+ foreach (var ps in gameObject.GetComponentsInChildren<ParticleSystem>(true))
+ {
+ driver.AddFromName<ParticleSystem>(ps.gameObject, "randomSeed");
+ driver.AddFromName<ParticleSystem>(ps.gameObject, "autoRandomSeed");
+ }
+ }
+
+ if (active)
+ {
+ driver.AddFromName(gameObject, "m_IsActive");
+ }
+
+ if (updateITimeControl)
+ {
+ foreach (var script in GetControlableScripts(gameObject))
+ {
+ var propertyPreview = script as IPropertyPreview;
+ if (propertyPreview != null)
+ propertyPreview.GatherProperties(director, driver);
+ else
+ driver.AddFromComponent(script.gameObject, script);
+ }
+ }
+
+ if (updateDirector)
+ {
+ foreach (var childDirector in GetComponent<PlayableDirector>(gameObject))
+ {
+ if (childDirector == null)
+ continue;
+
+ var timeline = childDirector.playableAsset as TimelineAsset;
+ if (timeline == null)
+ continue;
+
+ timeline.GatherProperties(childDirector, driver);
+ }
+ }
+ }
+ s_ProcessedDirectors.Remove(director);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs.meta
new file mode 100644
index 0000000..3f4d090
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlPlayableAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 48853ae485fa386428341ac1ea122570
+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/Control/ControlTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs
new file mode 100644
index 0000000..e42c9af
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A Track whose clips control time-related elements on a GameObject.
+ /// </summary>
+ [TrackClipType(typeof(ControlPlayableAsset), false)]
+ [ExcludeFromPreset]
+ public class ControlTrack : TrackAsset
+ {
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs.meta
new file mode 100644
index 0000000..95582da
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Control/ControlTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 15e0374501f39d54eb30235764636e0e
+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/DiscreteTime.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs
new file mode 100644
index 0000000..af68af8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs
@@ -0,0 +1,226 @@
+using System;
+
+namespace UnityEngine.Timeline
+{
+ struct DiscreteTime : IComparable
+ {
+ const double k_Tick = 1e-12;
+ public static readonly DiscreteTime kMaxTime = new DiscreteTime(Int64.MaxValue);
+
+ readonly Int64 m_DiscreteTime;
+
+ public static double tickValue { get { return k_Tick; } }
+
+ public DiscreteTime(DiscreteTime time)
+ {
+ m_DiscreteTime = time.m_DiscreteTime;
+ }
+
+ DiscreteTime(Int64 time)
+ {
+ m_DiscreteTime = time;
+ }
+
+ public DiscreteTime(double time)
+ {
+ m_DiscreteTime = DoubleToDiscreteTime(time);
+ }
+
+ public DiscreteTime(float time)
+ {
+ m_DiscreteTime = FloatToDiscreteTime(time);
+ }
+
+ public DiscreteTime(int time)
+ {
+ m_DiscreteTime = IntToDiscreteTime(time);
+ }
+
+ public DiscreteTime(int frame, double fps)
+ {
+ m_DiscreteTime = DoubleToDiscreteTime(frame * fps);
+ }
+
+ public DiscreteTime OneTickBefore()
+ {
+ return new DiscreteTime(m_DiscreteTime - 1);
+ }
+
+ public DiscreteTime OneTickAfter()
+ {
+ return new DiscreteTime(m_DiscreteTime + 1);
+ }
+
+ public Int64 GetTick()
+ {
+ return m_DiscreteTime;
+ }
+
+ public static DiscreteTime FromTicks(Int64 ticks)
+ {
+ return new DiscreteTime(ticks);
+ }
+
+ public int CompareTo(object obj)
+ {
+ if (obj is DiscreteTime)
+ return m_DiscreteTime.CompareTo(((DiscreteTime)obj).m_DiscreteTime);
+ return 1;
+ }
+
+ public bool Equals(DiscreteTime other)
+ {
+ return m_DiscreteTime == other.m_DiscreteTime;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is DiscreteTime)
+ return Equals((DiscreteTime)obj);
+ return false;
+ }
+
+ static Int64 DoubleToDiscreteTime(double time)
+ {
+ double number = (time / k_Tick) + 0.5;
+ if (number < Int64.MaxValue && number > Int64.MinValue)
+ return (Int64)number;
+ throw new ArgumentOutOfRangeException("Time is over the discrete range.");
+ }
+
+ static Int64 FloatToDiscreteTime(float time)
+ {
+ float number = (time / (float)k_Tick) + 0.5f;
+ if (number < Int64.MaxValue && number > Int64.MinValue)
+ return (Int64)number;
+ throw new ArgumentOutOfRangeException("Time is over the discrete range.");
+ }
+
+ static Int64 IntToDiscreteTime(int time)
+ {
+ return DoubleToDiscreteTime(time);
+ }
+
+ static double ToDouble(Int64 time)
+ {
+ return time * k_Tick;
+ }
+
+ static float ToFloat(Int64 time)
+ {
+ return (float)ToDouble(time);
+ }
+
+ public static explicit operator double(DiscreteTime b)
+ {
+ return ToDouble(b.m_DiscreteTime);
+ }
+
+ public static explicit operator float(DiscreteTime b)
+ {
+ return ToFloat(b.m_DiscreteTime);
+ }
+
+ public static explicit operator Int64(DiscreteTime b)
+ {
+ return b.m_DiscreteTime;
+ }
+
+ public static explicit operator DiscreteTime(double time)
+ {
+ return new DiscreteTime(time);
+ }
+
+ public static explicit operator DiscreteTime(float time)
+ {
+ return new DiscreteTime(time);
+ }
+
+ public static implicit operator DiscreteTime(Int32 time)
+ {
+ return new DiscreteTime(time);
+ }
+
+ public static explicit operator DiscreteTime(Int64 time)
+ {
+ return new DiscreteTime(time);
+ }
+
+ public static bool operator==(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return lhs.m_DiscreteTime == rhs.m_DiscreteTime;
+ }
+
+ public static bool operator!=(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ public static bool operator>(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return lhs.m_DiscreteTime > rhs.m_DiscreteTime;
+ }
+
+ public static bool operator<(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return lhs.m_DiscreteTime < rhs.m_DiscreteTime;
+ }
+
+ public static bool operator<=(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return lhs.m_DiscreteTime <= rhs.m_DiscreteTime;
+ }
+
+ public static bool operator>=(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return lhs.m_DiscreteTime >= rhs.m_DiscreteTime;
+ }
+
+ public static DiscreteTime operator+(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return new DiscreteTime(lhs.m_DiscreteTime + rhs.m_DiscreteTime);
+ }
+
+ public static DiscreteTime operator-(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return new DiscreteTime(lhs.m_DiscreteTime - rhs.m_DiscreteTime);
+ }
+
+ public override string ToString()
+ {
+ return m_DiscreteTime.ToString();
+ }
+
+ public override int GetHashCode()
+ {
+ return m_DiscreteTime.GetHashCode();
+ }
+
+ public static DiscreteTime Min(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return new DiscreteTime(Math.Min(lhs.m_DiscreteTime, rhs.m_DiscreteTime));
+ }
+
+ public static DiscreteTime Max(DiscreteTime lhs, DiscreteTime rhs)
+ {
+ return new DiscreteTime(Math.Max(lhs.m_DiscreteTime, rhs.m_DiscreteTime));
+ }
+
+ public static double SnapToNearestTick(double time)
+ {
+ Int64 discreteTime = DoubleToDiscreteTime(time);
+ return ToDouble(discreteTime);
+ }
+
+ public static float SnapToNearestTick(float time)
+ {
+ Int64 discreteTime = FloatToDiscreteTime(time);
+ return ToFloat(discreteTime);
+ }
+
+ public static Int64 GetNearestTick(double time)
+ {
+ return DoubleToDiscreteTime(time);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs.meta
new file mode 100644
index 0000000..e6d4977
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/DiscreteTime.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8beed9aab74505d488e6befe54c3f6ef
+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/Evaluation.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation.meta
new file mode 100644
index 0000000..433d36b
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4c6f60d349ea37048af03504fc872f33
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs
new file mode 100644
index 0000000..e833fd5
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs
@@ -0,0 +1,46 @@
+using System;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Runtime clip customized for 'infinite' tracks playables.
+ /// Used for clips whose time needs to match the timelines exactly
+ /// </summary>
+ class InfiniteRuntimeClip : RuntimeElement
+ {
+ private Playable m_Playable;
+ private static readonly Int64 kIntervalEnd = DiscreteTime.GetNearestTick(TimelineClip.kMaxTimeValue);
+
+ public InfiniteRuntimeClip(Playable playable)
+ {
+ m_Playable = playable;
+ }
+
+ public override Int64 intervalStart
+ {
+ get { return 0; }
+ }
+
+ public override Int64 intervalEnd
+ {
+ get { return kIntervalEnd; }
+ }
+
+ public override bool enable
+ {
+ set
+ {
+ if (value)
+ m_Playable.Play();
+ else
+ m_Playable.Pause();
+ }
+ }
+
+ public override void EvaluateAt(double localTime, FrameData frameData)
+ {
+ m_Playable.SetTime(localTime);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs.meta
new file mode 100644
index 0000000..c0451a6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/InfiniteRuntimeClip.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9b5abcb38bac0c54794ad732a3fa0de3
+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/Evaluation/IntervalTree.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs
new file mode 100644
index 0000000..691f477
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs
@@ -0,0 +1,271 @@
+using System;
+using System.Collections.Generic;
+
+namespace UnityEngine.Timeline
+{
+ interface IInterval
+ {
+ Int64 intervalStart { get; }
+ Int64 intervalEnd { get; }
+ }
+
+ struct IntervalTreeNode // interval node,
+ {
+ public Int64 center; // midpoint for this node
+ public int first; // index of first element of this node in m_Entries
+ public int last; // index of the last element of this node in m_Entries
+ public int left; // index in m_Nodes of the left subnode
+ public int right; // index in m_Nodes of the right subnode
+ }
+
+ class IntervalTree<T> where T : IInterval
+ {
+ internal struct Entry
+ {
+ public Int64 intervalStart;
+ public Int64 intervalEnd;
+ public T item;
+ }
+
+ const int kMinNodeSize = 10; // the minimum number of entries to have subnodes
+ const int kInvalidNode = -1;
+ const Int64 kCenterUnknown = Int64.MaxValue; // center hasn't been calculated. indicates no children
+
+ readonly List<Entry> m_Entries = new List<Entry>();
+ readonly List<IntervalTreeNode> m_Nodes = new List<IntervalTreeNode>();
+
+ /// <summary>
+ /// Whether the tree will be rebuilt on the next query
+ /// </summary>
+ public bool dirty { get; internal set; }
+
+ /// <summary>
+ /// Add an IInterval to the tree
+ /// </summary>
+ public void Add(T item)
+ {
+ if (item == null)
+ return;
+
+ m_Entries.Add(
+ new Entry()
+ {
+ intervalStart = item.intervalStart,
+ intervalEnd = item.intervalEnd,
+ item = item
+ }
+ );
+ dirty = true;
+ }
+
+ /// <summary>
+ /// Query the tree at a particular time
+ /// </summary>
+ /// <param name="value"></param>
+ /// <param name="results"></param>
+ public void IntersectsWith(Int64 value, List<T> results)
+ {
+ if (m_Entries.Count == 0)
+ return;
+
+ if (dirty)
+ {
+ Rebuild();
+ dirty = false;
+ }
+
+ if (m_Nodes.Count > 0)
+ Query(m_Nodes[0], value, results);
+ }
+
+ /// <summary>
+ /// Query the tree at a particular range of time
+ /// </summary>
+ /// <param name="start"></param>
+ /// <param name="end"></param>
+ /// <param name="results"></param>
+ public void IntersectsWithRange(Int64 start, Int64 end, List<T> results)
+ {
+ if (start > end)
+ return;
+
+ if (m_Entries.Count == 0)
+ return;
+
+ if (dirty)
+ {
+ Rebuild();
+ dirty = false;
+ }
+
+ if (m_Nodes.Count > 0)
+ QueryRange(m_Nodes[0], start, end, results);
+ }
+
+ /// <summary>
+ /// Updates the intervals from their source. Use this to detect if the data in the tree
+ /// has changed.
+ /// </summary>
+ public void UpdateIntervals()
+ {
+ bool isDirty = false;
+ for (int i = 0; i < m_Entries.Count; i++)
+ {
+ var n = m_Entries[i];
+ var s = n.item.intervalStart;
+ var e = n.item.intervalEnd;
+
+ isDirty |= n.intervalStart != s;
+ isDirty |= n.intervalEnd != e;
+
+ m_Entries[i] = new Entry()
+ {
+ intervalStart = s,
+ intervalEnd = e,
+ item = n.item
+ };
+ }
+
+ dirty |= isDirty;
+ }
+
+ private void Query(IntervalTreeNode intervalTreeNode, Int64 value, List<T> results)
+ {
+ for (int i = intervalTreeNode.first; i <= intervalTreeNode.last; i++)
+ {
+ var entry = m_Entries[i];
+ if (value >= entry.intervalStart && value < entry.intervalEnd)
+ {
+ results.Add(entry.item);
+ }
+ }
+
+ if (intervalTreeNode.center == kCenterUnknown)
+ return;
+ if (intervalTreeNode.left != kInvalidNode && value < intervalTreeNode.center)
+ Query(m_Nodes[intervalTreeNode.left], value, results);
+ if (intervalTreeNode.right != kInvalidNode && value > intervalTreeNode.center)
+ Query(m_Nodes[intervalTreeNode.right], value, results);
+ }
+
+ private void QueryRange(IntervalTreeNode intervalTreeNode, Int64 start, Int64 end, List<T> results)
+ {
+ for (int i = intervalTreeNode.first; i <= intervalTreeNode.last; i++)
+ {
+ var entry = m_Entries[i];
+ if (end >= entry.intervalStart && start < entry.intervalEnd)
+ {
+ results.Add(entry.item);
+ }
+ }
+
+ if (intervalTreeNode.center == kCenterUnknown)
+ return;
+ if (intervalTreeNode.left != kInvalidNode && start < intervalTreeNode.center)
+ QueryRange(m_Nodes[intervalTreeNode.left], start, end, results);
+ if (intervalTreeNode.right != kInvalidNode && end > intervalTreeNode.center)
+ QueryRange(m_Nodes[intervalTreeNode.right], start, end, results);
+ }
+
+ private void Rebuild()
+ {
+ m_Nodes.Clear();
+ m_Nodes.Capacity = m_Entries.Capacity;
+ Rebuild(0, m_Entries.Count - 1);
+ }
+
+ private int Rebuild(int start, int end)
+ {
+ IntervalTreeNode intervalTreeNode = new IntervalTreeNode();
+
+ // minimum size, don't subdivide
+ int count = end - start + 1;
+ if (count < kMinNodeSize)
+ {
+ intervalTreeNode = new IntervalTreeNode() {center = kCenterUnknown, first = start, last = end, left = kInvalidNode, right = kInvalidNode};
+ m_Nodes.Add(intervalTreeNode);
+ return m_Nodes.Count - 1;
+ }
+
+ var min = Int64.MaxValue;
+ var max = Int64.MinValue;
+
+ for (int i = start; i <= end; i++)
+ {
+ var o = m_Entries[i];
+ min = Math.Min(min, o.intervalStart);
+ max = Math.Max(max, o.intervalEnd);
+ }
+
+ var center = (max + min) / 2;
+ intervalTreeNode.center = center;
+
+ // first pass, put every thing left of center, left
+ int x = start;
+ int y = end;
+ while (true)
+ {
+ while (x <= end && m_Entries[x].intervalEnd < center)
+ x++;
+
+ while (y >= start && m_Entries[y].intervalEnd >= center)
+ y--;
+
+ if (x > y)
+ break;
+
+ var nodeX = m_Entries[x];
+ var nodeY = m_Entries[y];
+
+ m_Entries[y] = nodeX;
+ m_Entries[x] = nodeY;
+ }
+
+ intervalTreeNode.first = x;
+
+ // second pass, put every start passed the center right
+ y = end;
+ while (true)
+ {
+ while (x <= end && m_Entries[x].intervalStart <= center)
+ x++;
+
+ while (y >= start && m_Entries[y].intervalStart > center)
+ y--;
+
+ if (x > y)
+ break;
+
+ var nodeX = m_Entries[x];
+ var nodeY = m_Entries[y];
+
+ m_Entries[y] = nodeX;
+ m_Entries[x] = nodeY;
+ }
+
+ intervalTreeNode.last = y;
+
+ // reserve a place
+ m_Nodes.Add(new IntervalTreeNode());
+ int index = m_Nodes.Count - 1;
+
+ intervalTreeNode.left = kInvalidNode;
+ intervalTreeNode.right = kInvalidNode;
+
+ if (start < intervalTreeNode.first)
+ intervalTreeNode.left = Rebuild(start, intervalTreeNode.first - 1);
+
+ if (end > intervalTreeNode.last)
+ intervalTreeNode.right = Rebuild(intervalTreeNode.last + 1, end);
+
+ m_Nodes[index] = intervalTreeNode;
+ return index;
+ }
+
+ public void Clear()
+ {
+ m_Entries.Clear();
+ m_Nodes.Clear();
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs.meta
new file mode 100644
index 0000000..cf954ab
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/IntervalTree.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8f74c99a65464bb4b86ccb314ee95a7f
+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/Evaluation/RuntimeClip.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs
new file mode 100644
index 0000000..9b260cd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs
@@ -0,0 +1,110 @@
+using UnityEngine;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ // The RuntimeClip wraps a single clip in an instantiated sequence.
+ // It supports the IInterval interface so that it can be stored in the interval tree
+ // It is this class that is returned by an interval tree query.
+ class RuntimeClip : RuntimeClipBase
+ {
+ TimelineClip m_Clip;
+ Playable m_Playable;
+ Playable m_ParentMixer;
+
+ public override double start
+ {
+ get { return m_Clip.extrapolatedStart; }
+ }
+
+ public override double duration
+ {
+ get { return m_Clip.extrapolatedDuration; }
+ }
+
+ public RuntimeClip(TimelineClip clip, Playable clipPlayable, Playable parentMixer)
+ {
+ Create(clip, clipPlayable, parentMixer);
+ }
+
+ void Create(TimelineClip clip, Playable clipPlayable, Playable parentMixer)
+ {
+ m_Clip = clip;
+ m_Playable = clipPlayable;
+ m_ParentMixer = parentMixer;
+ clipPlayable.Pause();
+ }
+
+ public TimelineClip clip
+ {
+ get { return m_Clip; }
+ }
+
+ public Playable mixer
+ {
+ get { return m_ParentMixer; }
+ }
+
+ public Playable playable
+ {
+ get { return m_Playable; }
+ }
+
+ public override bool enable
+ {
+ set
+ {
+ if (value && m_Playable.GetPlayState() != PlayState.Playing)
+ {
+ m_Playable.Play();
+ SetTime(m_Clip.clipIn);
+ }
+ else if (!value && m_Playable.GetPlayState() != PlayState.Paused)
+ {
+ m_Playable.Pause();
+ if (m_ParentMixer.IsValid())
+ m_ParentMixer.SetInputWeight(m_Playable, 0.0f);
+ }
+ }
+ }
+
+ public void SetTime(double time)
+ {
+ m_Playable.SetTime(time);
+ }
+
+ public void SetDuration(double duration)
+ {
+ m_Playable.SetDuration(duration);
+ }
+
+ public override void EvaluateAt(double localTime, FrameData frameData)
+ {
+ enable = true;
+
+ float weight = 1.0f;
+ if (clip.IsPreExtrapolatedTime(localTime))
+ weight = clip.EvaluateMixIn((float)clip.start);
+ else if (clip.IsPostExtrapolatedTime(localTime))
+ weight = clip.EvaluateMixOut((float)clip.end);
+ else
+ weight = clip.EvaluateMixIn(localTime) * clip.EvaluateMixOut(localTime);
+
+ if (mixer.IsValid())
+ mixer.SetInputWeight(playable, weight);
+
+ // localTime of the sequence to localtime of the clip
+ double clipTime = clip.ToLocalTime(localTime);
+ if (clipTime.CompareTo(0.0) >= 0)
+ {
+ SetTime(clipTime);
+ }
+ SetDuration(clip.extrapolatedDuration);
+ }
+
+ public override void Reset()
+ {
+ SetTime(m_Clip.clipIn);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs.meta
new file mode 100644
index 0000000..3ae5d53
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClip.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 70a190a1b304d1e43995af35d09231d6
+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/Evaluation/RuntimeClipBase.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs
new file mode 100644
index 0000000..f6a178a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs
@@ -0,0 +1,21 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Timeline
+{
+ internal abstract class RuntimeClipBase : RuntimeElement
+ {
+ public abstract double start { get; }
+ public abstract double duration { get; }
+
+ public override Int64 intervalStart
+ {
+ get { return DiscreteTime.GetNearestTick(start); }
+ }
+
+ public override Int64 intervalEnd
+ {
+ get { return DiscreteTime.GetNearestTick(start + duration); }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs.meta
new file mode 100644
index 0000000..49f3b62
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeClipBase.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 70f955bbb437a494888ef54d97abb474
+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/Evaluation/RuntimeElement.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs
new file mode 100644
index 0000000..bdd7f11
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs
@@ -0,0 +1,17 @@
+using System;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ abstract class RuntimeElement : IInterval
+ {
+ public abstract Int64 intervalStart { get; }
+ public abstract Int64 intervalEnd { get; }
+ public int intervalBit { get; set; }
+
+ public abstract bool enable { set; }
+ public abstract void EvaluateAt(double localTime, FrameData frameData);
+
+ public virtual void Reset() {}
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs.meta
new file mode 100644
index 0000000..03b8737
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/RuntimeElement.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 76b6bf32a6fcf934aab8c529bddccc81
+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/Evaluation/ScheduleRuntimeClip.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs
new file mode 100644
index 0000000..4831cc4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs
@@ -0,0 +1,111 @@
+using System;
+using UnityEngine;
+using UnityEngine.Audio;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ // Special runtime clip implementation that handles playables that use a scheduling system
+ // such as Audio
+ internal class ScheduleRuntimeClip : RuntimeClipBase
+ {
+ private TimelineClip m_Clip;
+ private Playable m_Playable;
+ private Playable m_ParentMixer;
+ private double m_StartDelay;
+ private double m_FinishTail;
+ private bool m_Started = false;
+
+ // represents the start point when we want to start getting updated
+ public override double start
+ {
+ get { return Math.Max(0, m_Clip.start - m_StartDelay); }
+ }
+
+ public override double duration
+ {
+ get { return m_Clip.duration + m_FinishTail + m_Clip.start - start; }
+ }
+
+ public void SetTime(double time)
+ {
+ m_Playable.SetTime(time);
+ }
+
+ public TimelineClip clip { get { return m_Clip; } }
+ public Playable mixer { get { return m_ParentMixer; } }
+ public Playable playable { get { return m_Playable; } }
+
+ public ScheduleRuntimeClip(TimelineClip clip, Playable clipPlayable,
+ Playable parentMixer, double startDelay = 0.2, double finishTail = 0.1)
+ {
+ Create(clip, clipPlayable, parentMixer, startDelay, finishTail);
+ }
+
+ private void Create(TimelineClip clip, Playable clipPlayable, Playable parentMixer,
+ double startDelay, double finishTail)
+ {
+ m_Clip = clip;
+ m_Playable = clipPlayable;
+ m_ParentMixer = parentMixer;
+ m_StartDelay = startDelay;
+ m_FinishTail = finishTail;
+ clipPlayable.Pause();
+ }
+
+ public override bool enable
+ {
+ set
+ {
+ if (value && m_Playable.GetPlayState() != PlayState.Playing)
+ {
+ m_Playable.Play();
+ }
+ else if (!value && m_Playable.GetPlayState() != PlayState.Paused)
+ {
+ m_Playable.Pause();
+ if (m_ParentMixer.IsValid())
+ m_ParentMixer.SetInputWeight(m_Playable, 0.0f);
+ }
+
+ m_Started &= value;
+ }
+ }
+
+ public override void EvaluateAt(double localTime, FrameData frameData)
+ {
+ if (frameData.timeHeld)
+ {
+ enable = false;
+ return;
+ }
+
+
+ bool forceSeek = frameData.seekOccurred || frameData.timeLooped || frameData.evaluationType == FrameData.EvaluationType.Evaluate;
+
+ // If we are in the tail region of the clip, then dont do anything
+ if (localTime > start + duration - m_FinishTail)
+ return;
+
+ // this may set the weight to 1 in a delay, but it will avoid missing the start
+ float weight = clip.EvaluateMixIn(localTime) * clip.EvaluateMixOut(localTime);
+ if (mixer.IsValid())
+ mixer.SetInputWeight(playable, weight);
+
+ // localTime of the sequence to localtime of the clip
+ if (!m_Started || forceSeek)
+ {
+ // accounts for clip in and speed
+ double clipTime = clip.ToLocalTime(Math.Max(localTime, clip.start));
+ // multiply by the time scale so the delay is local to the clip
+ // Audio will rescale based on it's effective time scale (which includes the parent)
+ double startDelay = Math.Max(clip.start - localTime, 0) * clip.timeScale;
+ double durationLocal = m_Clip.duration * clip.timeScale;
+ if (m_Playable.IsPlayableOfType<AudioClipPlayable>())
+ ((AudioClipPlayable)m_Playable).Seek(clipTime, startDelay, durationLocal);
+
+ m_Started = true;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs.meta
new file mode 100644
index 0000000..b3ea114
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Evaluation/ScheduleRuntimeClip.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b250be9db55288b48ac121c074d795e6
+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/Events.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events.meta
new file mode 100644
index 0000000..847f9d1
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b8c5993172f27e4419d7d4ed5ef77840
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs
new file mode 100644
index 0000000..2595cdf
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs
@@ -0,0 +1,31 @@
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Interface implemented by markers.
+ /// </summary>
+ /// <remarks>
+ /// A marker is a point in time.
+ /// </remarks>
+ /// <seealso cref="UnityEngine.Timeline.Marker"/>
+ public interface IMarker
+ {
+ /// <summary>
+ /// The time set for the marker, in seconds.
+ /// </summary>
+ double time { get; set; }
+
+ /// <summary>
+ /// The track that contains the marker.
+ /// </summary>
+ TrackAsset parent { get; }
+
+ /// <summary>
+ /// This method is called when the marker is initialized.
+ /// </summary>
+ /// <param name="parent">The track that contains the marker.</param>
+ /// <remarks>
+ /// This method is called after each deserialization of the Timeline Asset.
+ /// </remarks>
+ void Initialize(TrackAsset parent);
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs.meta
new file mode 100644
index 0000000..3869cbc
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/IMarker.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4cb169caa67eddf4d83b39fd0917a945
+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/Events/INotificationOptionProvider.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs
new file mode 100644
index 0000000..7a23d7d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs
@@ -0,0 +1,15 @@
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Implement this interface to change the behaviour of an INotification.
+ /// </summary>
+ /// This interface must be implemented along with <see cref="UnityEngine.Playables.INotification"/> to modify the default behaviour of a notification.
+ /// <seealso cref="UnityEngine.Timeline.NotificationFlags"/>
+ public interface INotificationOptionProvider
+ {
+ /// <summary>
+ /// The flags that change the triggering behaviour.
+ /// </summary>
+ NotificationFlags flags { get; }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs.meta
new file mode 100644
index 0000000..3e59b72
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/INotificationOptionProvider.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5082cb99a8f99b84d84dd8b4c5233a9e
+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/Events/Marker.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs
new file mode 100644
index 0000000..2f12cd7
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs
@@ -0,0 +1,53 @@
+using System;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Use Marker as a base class when creating a custom marker.
+ /// </summary>
+ /// <remarks>
+ /// A marker is a point in time.
+ /// </remarks>
+ public abstract class Marker : ScriptableObject, IMarker
+ {
+ [SerializeField, TimeField, Tooltip("Time for the marker")] double m_Time;
+
+ /// <inheritdoc/>
+ public TrackAsset parent { get; private set; }
+
+ /// <inheritdoc/>
+ /// <remarks>
+ /// The marker time cannot be negative.
+ /// </remarks>
+ public double time
+ {
+ get { return m_Time; }
+ set { m_Time = Math.Max(value, 0); }
+ }
+
+ void IMarker.Initialize(TrackAsset parentTrack)
+ {
+ // We only really want to update the parent when the object is first deserialized
+ // If not a cloned track would "steal" the source's markers
+ if (parent == null)
+ {
+ parent = parentTrack;
+ try
+ {
+ OnInitialize(parentTrack);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.Message, this);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Override this method to receive a callback when the marker is initialized.
+ /// </summary>
+ public virtual void OnInitialize(TrackAsset aPent)
+ {
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs.meta
new file mode 100644
index 0000000..2bb36b5
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Marker.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 89b48a03f6f43e94e87cc8d2104d3d4d
+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/Events/MarkerList.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs
new file mode 100644
index 0000000..4be4fc2
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs
@@ -0,0 +1,168 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ [Serializable]
+ struct MarkerList : ISerializationCallbackReceiver
+ {
+ [SerializeField, HideInInspector] List<ScriptableObject> m_Objects;
+
+ [HideInInspector, NonSerialized] List<IMarker> m_Cache;
+ bool m_CacheDirty;
+ bool m_HasNotifications;
+ public List<IMarker> markers
+ {
+ get
+ {
+ BuildCache();
+ return m_Cache;
+ }
+ }
+
+ public MarkerList(int capacity)
+ {
+ m_Objects = new List<ScriptableObject>(capacity);
+ m_Cache = new List<IMarker>(capacity);
+ m_CacheDirty = true;
+ m_HasNotifications = false;
+ }
+
+ public void Add(ScriptableObject item)
+ {
+ if (item == null)
+ return;
+
+ m_Objects.Add(item);
+ m_CacheDirty = true;
+ }
+
+ public bool Remove(IMarker item)
+ {
+ if (!(item is ScriptableObject))
+ throw new InvalidOperationException("Supplied type must be a ScriptableObject");
+ return Remove((ScriptableObject)item, item.parent.timelineAsset, item.parent);
+ }
+
+ public bool Remove(ScriptableObject item, TimelineAsset timelineAsset, PlayableAsset thingToDirty)
+ {
+ if (!m_Objects.Contains(item)) return false;
+
+ TimelineUndo.PushUndo(thingToDirty, "Delete Marker");
+ m_Objects.Remove(item);
+ m_CacheDirty = true;
+ TimelineUndo.PushDestroyUndo(timelineAsset, thingToDirty, item, "Delete Marker");
+ return true;
+ }
+
+ public void Clear()
+ {
+ m_Objects.Clear();
+ m_CacheDirty = true;
+ }
+
+ public bool Contains(ScriptableObject item)
+ {
+ return m_Objects.Contains(item);
+ }
+
+ public IEnumerable<IMarker> GetMarkers()
+ {
+ return markers;
+ }
+
+ public int Count
+ {
+ get { return markers.Count; }
+ }
+
+ public IMarker this[int idx]
+ {
+ get
+ {
+ return markers[idx];
+ }
+ }
+
+ public List<ScriptableObject> GetRawMarkerList()
+ {
+ return m_Objects;
+ }
+
+ public IMarker CreateMarker(Type type, double time, TrackAsset owner)
+ {
+ if (!typeof(ScriptableObject).IsAssignableFrom(type) || !typeof(IMarker).IsAssignableFrom(type))
+ {
+ throw new InvalidOperationException(
+ "The requested type needs to inherit from ScriptableObject and implement IMarker");
+ }
+ if (!owner.supportsNotifications && typeof(INotification).IsAssignableFrom(type))
+ {
+ throw new InvalidOperationException(
+ "Markers implementing the INotification interface cannot be added on tracks that do not support notifications");
+ }
+
+ var markerSO = ScriptableObject.CreateInstance(type);
+ var marker = (IMarker)markerSO;
+ marker.time = time;
+
+ TimelineCreateUtilities.SaveAssetIntoObject(markerSO, owner);
+ TimelineUndo.RegisterCreatedObjectUndo(markerSO, "Create " + type.Name);
+ TimelineUndo.PushUndo(owner, "Create " + type.Name);
+
+ Add(markerSO);
+ marker.Initialize(owner);
+
+ return marker;
+ }
+
+ public bool HasNotifications()
+ {
+ BuildCache();
+ return m_HasNotifications;
+ }
+
+ void ISerializationCallbackReceiver.OnBeforeSerialize()
+ {
+ }
+
+ void ISerializationCallbackReceiver.OnAfterDeserialize()
+ {
+#if UNITY_EDITOR
+ for (int i = m_Objects.Count - 1; i >= 0; i--)
+ {
+ object o = m_Objects[i];
+ if (o == null)
+ {
+ Debug.LogWarning("Empty marker found while loading timeline. It will be removed.");
+ m_Objects.RemoveAt(i);
+ }
+ }
+#endif
+ m_CacheDirty = true;
+ }
+
+ void BuildCache()
+ {
+ if (m_CacheDirty)
+ {
+ m_Cache = new List<IMarker>(m_Objects.Count);
+ m_HasNotifications = false;
+ foreach (var o in m_Objects)
+ {
+ if (o != null)
+ {
+ m_Cache.Add(o as IMarker);
+ if (o is INotification)
+ {
+ m_HasNotifications = true;
+ }
+ }
+ }
+
+ m_CacheDirty = false;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs.meta
new file mode 100644
index 0000000..1875712
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerList.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4335a164bb763104c8805212c23d795f
+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/Events/MarkerTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs
new file mode 100644
index 0000000..f64b483
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <inheritdoc />
+ /// <summary>
+ /// Use this track to add Markers bound to a GameObject.
+ /// </summary>
+ [Serializable]
+ [TrackBindingType(typeof(GameObject))]
+ [HideInMenu]
+ [ExcludeFromPreset]
+ public class MarkerTrack : TrackAsset
+ {
+ /// <inheritdoc/>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get
+ {
+ return this == timelineAsset.markerTrack ?
+ new List<PlayableBinding> {ScriptPlayableBinding.Create(name, null, typeof(GameObject))} :
+ base.outputs;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs.meta
new file mode 100644
index 0000000..37ca389
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/MarkerTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2a16748d9461eae46a725db9776d5390
+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/Events/SignalTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs
new file mode 100644
index 0000000..7c7bc4e
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Use this track to emit signals to a bound SignalReceiver.
+ /// </summary>
+ /// <remarks>
+ /// This track cannot contain clips.
+ /// </remarks>
+ /// <seealso cref="UnityEngine.Timeline.SignalEmitter"/>
+ /// <seealso cref="UnityEngine.Timeline.SignalReceiver"/>
+ /// <seealso cref="UnityEngine.Timeline.SignalAsset"/>
+ [Serializable]
+ [TrackBindingType(typeof(SignalReceiver))]
+ [TrackColor(0.25f, 0.25f, 0.25f)]
+ [ExcludeFromPreset]
+ public class SignalTrack : MarkerTrack {}
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs.meta
new file mode 100644
index 0000000..3343f84
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/SignalTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b46e36075dd1c124a8422c228e75e1fb
+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/Events/Signals.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals.meta
new file mode 100644
index 0000000..aa956e4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5b00473355622524394628f7ec51808d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs
new file mode 100644
index 0000000..49df674
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs
@@ -0,0 +1,5 @@
+namespace UnityEngine.Timeline
+{
+ //used to tell Signal Handler inspector to use a special drawer for UnityEvent
+ class CustomSignalEventDrawer : PropertyAttribute {}
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs.meta
new file mode 100644
index 0000000..c7c813f
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/CustomSignalEventDrawer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a7ebd1239373d5f41af65ef32d67f445
+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/Events/Signals/SignalAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs
new file mode 100644
index 0000000..d605588
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs
@@ -0,0 +1,22 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// An asset representing an emitted signal. A SignalAsset connects a SignalEmitter with a SignalReceiver.
+ /// </summary>
+ /// <seealso cref="UnityEngine.Timeline.SignalEmitter"/>
+ /// <seealso cref="UnityEngine.Timeline.SignalReceiver"/>
+ [AssetFileNameExtension("signal")]
+ public class SignalAsset : ScriptableObject
+ {
+ internal static event Action<SignalAsset> OnEnableCallback;
+
+ void OnEnable()
+ {
+ if (OnEnableCallback != null)
+ OnEnableCallback(this);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs.meta
new file mode 100644
index 0000000..437f4d3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d6fa2d92fc1b3f34da284357edf89c3b
+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/Events/Signals/SignalEmitter.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs
new file mode 100644
index 0000000..d4d4ca9
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs
@@ -0,0 +1,72 @@
+using System;
+using UnityEngine;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <inheritdoc cref="UnityEngine.Timeline.IMarker" />
+ /// <summary>
+ /// Marker that emits a signal to a SignalReceiver.
+ /// </summary>
+ /// A SignalEmitter emits a notification through the playable system. A SignalEmitter is used with a SignalReceiver and a SignalAsset.
+ /// <seealso cref="UnityEngine.Timeline.SignalAsset"/>
+ /// <seealso cref="UnityEngine.Timeline.SignalReceiver"/>
+ [Serializable]
+ [CustomStyle("SignalEmitter")]
+ [ExcludeFromPreset]
+ public class SignalEmitter : Marker, INotification, INotificationOptionProvider
+ {
+ [SerializeField] bool m_Retroactive;
+ [SerializeField] bool m_EmitOnce;
+ [SerializeField] SignalAsset m_Asset;
+
+ /// <summary>
+ /// Use retroactive to emit the signal if playback starts after the SignalEmitter time.
+ /// </summary>
+ public bool retroactive
+ {
+ get { return m_Retroactive; }
+ set { m_Retroactive = value; }
+ }
+
+ /// <summary>
+ /// Use emitOnce to emit this signal once during loops.
+ /// </summary>
+ public bool emitOnce
+ {
+ get { return m_EmitOnce; }
+ set { m_EmitOnce = value; }
+ }
+
+ /// <summary>
+ /// Asset representing the signal being emitted.
+ /// </summary>
+ public SignalAsset asset
+ {
+ get { return m_Asset; }
+ set { m_Asset = value; }
+ }
+
+ PropertyName INotification.id
+ {
+ get
+ {
+ if (m_Asset != null)
+ {
+ return new PropertyName(m_Asset.name);
+ }
+ return new PropertyName(string.Empty);
+ }
+ }
+
+ NotificationFlags INotificationOptionProvider.flags
+ {
+ get
+ {
+ return (retroactive ? NotificationFlags.Retroactive : default(NotificationFlags)) |
+ (emitOnce ? NotificationFlags.TriggerOnce : default(NotificationFlags)) |
+ NotificationFlags.TriggerInEditMode;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs.meta
new file mode 100644
index 0000000..f14c8a3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalEmitter.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 15c38f6fa1940124db1ab7f6fe7268d1
+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/Events/Signals/SignalReceiver.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs
new file mode 100644
index 0000000..4e7564a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs
@@ -0,0 +1,248 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Events;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Listens for emitted signals and reacts depending on its defined reactions.
+ /// </summary>
+ /// A SignalReceiver contains a list of reactions. Each reaction is bound to a SignalAsset.
+ /// When a SignalEmitter emits a signal, the SignalReceiver invokes the corresponding reaction.
+ /// <seealso cref="UnityEngine.Timeline.SignalEmitter"/>
+ /// <seealso cref="UnityEngine.Timeline.SignalAsset"/>
+ public class SignalReceiver : MonoBehaviour, INotificationReceiver
+ {
+ [SerializeField]
+ EventKeyValue m_Events = new EventKeyValue();
+
+ /// <summary>
+ /// Called when a notification is sent.
+ /// </summary>
+ public void OnNotify(Playable origin, INotification notification, object context)
+ {
+ var signal = notification as SignalEmitter;
+ if (signal != null && signal.asset != null)
+ {
+ UnityEvent evt;
+ if (m_Events.TryGetValue(signal.asset, out evt) && evt != null)
+ {
+ evt.Invoke();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Defines a new reaction for a SignalAsset.
+ /// </summary>
+ /// <param name="asset">The SignalAsset for which the reaction is being defined.</param>
+ /// <param name="reaction">The UnityEvent that describes the reaction.</param>
+ /// <exception cref="ArgumentNullException">Thrown when the asset is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when the SignalAsset is already registered with this receiver.</exception>
+ public void AddReaction(SignalAsset asset, UnityEvent reaction)
+ {
+ if (asset == null)
+ throw new ArgumentNullException("asset");
+
+ if (m_Events.signals.Contains(asset))
+ throw new ArgumentException("SignalAsset already used.");
+ m_Events.Append(asset, reaction);
+ }
+
+ /// <summary>
+ /// Appends a null SignalAsset with a reaction specified by the UnityEvent.
+ /// </summary>
+ /// <param name="reaction">The new reaction to be appended.</param>
+ /// <returns>The index of the appended reaction.</returns>
+ /// <remarks>Multiple null assets are valid.</remarks>
+ public int AddEmptyReaction(UnityEvent reaction)
+ {
+ m_Events.Append(null, reaction);
+ return m_Events.events.Count - 1;
+ }
+
+ /// <summary>
+ /// Removes the first occurrence of a SignalAsset.
+ /// </summary>
+ /// <param name="asset">The SignalAsset to be removed.</param>
+ public void Remove(SignalAsset asset)
+ {
+ if (!m_Events.signals.Contains(asset))
+ {
+ throw new ArgumentException("The SignalAsset is not registered with this receiver.");
+ }
+
+ m_Events.Remove(asset);
+ }
+
+ /// <summary>
+ /// Gets a list of all registered SignalAssets.
+ /// </summary>
+ /// <returns>Returns a list of SignalAssets.</returns>
+ public IEnumerable<SignalAsset> GetRegisteredSignals()
+ {
+ return m_Events.signals;
+ }
+
+ /// <summary>
+ /// Gets the first UnityEvent associated with a SignalAsset.
+ /// </summary>
+ /// <param name="key">A SignalAsset defining the signal.</param>
+ /// <returns>Returns the reaction associated with a SignalAsset. Returns null if the signal asset does not exist.</returns>
+ public UnityEvent GetReaction(SignalAsset key)
+ {
+ UnityEvent ret;
+ if (m_Events.TryGetValue(key, out ret))
+ {
+ return ret;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Returns the count of registered SignalAssets.
+ /// </summary>
+ /// <returns></returns>
+ public int Count()
+ {
+ return m_Events.signals.Count;
+ }
+
+ /// <summary>
+ /// Replaces the SignalAsset associated with a reaction at a specific index.
+ /// </summary>
+ /// <param name="idx">The index of the reaction.</param>
+ /// <param name="newKey">The replacement SignalAsset.</param>
+ /// <exception cref="ArgumentException">Thrown when the replacement SignalAsset is already registered to this SignalReceiver.</exception>
+ /// <remarks>The new SignalAsset can be null.</remarks>
+ public void ChangeSignalAtIndex(int idx, SignalAsset newKey)
+ {
+ if (idx < 0 || idx > m_Events.signals.Count - 1)
+ throw new IndexOutOfRangeException();
+
+ if (m_Events.signals[idx] == newKey)
+ return;
+ var alreadyUsed = m_Events.signals.Contains(newKey);
+ if (newKey == null || m_Events.signals[idx] == null || !alreadyUsed)
+ m_Events.signals[idx] = newKey;
+
+ if (newKey != null && alreadyUsed)
+ throw new ArgumentException("SignalAsset already used.");
+ }
+
+ /// <summary>
+ /// Removes the SignalAsset and reaction at a specific index.
+ /// </summary>
+ /// <param name="idx">The index of the SignalAsset to be removed.</param>
+ public void RemoveAtIndex(int idx)
+ {
+ if (idx < 0 || idx > m_Events.signals.Count - 1)
+ throw new IndexOutOfRangeException();
+ m_Events.Remove(idx);
+ }
+
+ /// <summary>
+ /// Replaces the reaction at a specific index with a new UnityEvent.
+ /// </summary>
+ /// <param name="idx">The index of the reaction to be replaced.</param>
+ /// <param name="reaction">The replacement reaction.</param>
+ /// <exception cref="ArgumentNullException">Thrown when the replacement reaction is null.</exception>
+ public void ChangeReactionAtIndex(int idx, UnityEvent reaction)
+ {
+ if (idx < 0 || idx > m_Events.events.Count - 1)
+ throw new IndexOutOfRangeException();
+
+ m_Events.events[idx] = reaction;
+ }
+
+ /// <summary>
+ /// Gets the reaction at a specific index.
+ /// </summary>
+ /// <param name="idx">The index of the reaction.</param>
+ /// <returns>Returns a reaction.</returns>
+ public UnityEvent GetReactionAtIndex(int idx)
+ {
+ if (idx < 0 || idx > m_Events.events.Count - 1)
+ throw new IndexOutOfRangeException();
+ return m_Events.events[idx];
+ }
+
+ /// <summary>
+ /// Gets the SignalAsset at a specific index
+ /// </summary>
+ /// <param name="idx">The index of the SignalAsset.</param>
+ /// <returns>Returns a SignalAsset.</returns>
+ public SignalAsset GetSignalAssetAtIndex(int idx)
+ {
+ if (idx < 0 || idx > m_Events.signals.Count - 1)
+ throw new IndexOutOfRangeException();
+ return m_Events.signals[idx];
+ }
+
+ // Required by Unity for the MonoBehaviour to have an enabled state
+ private void OnEnable()
+ {
+ }
+
+ [Serializable]
+ class EventKeyValue
+ {
+ [SerializeField]
+ List<SignalAsset> m_Signals = new List<SignalAsset>();
+
+ [SerializeField, CustomSignalEventDrawer]
+ List<UnityEvent> m_Events = new List<UnityEvent>();
+
+ public bool TryGetValue(SignalAsset key, out UnityEvent value)
+ {
+ var index = m_Signals.IndexOf(key);
+ if (index != -1)
+ {
+ value = m_Events[index];
+ return true;
+ }
+
+ value = null;
+ return false;
+ }
+
+ public void Append(SignalAsset key, UnityEvent value)
+ {
+ m_Signals.Add(key);
+ m_Events.Add(value);
+ }
+
+ public void Remove(int idx)
+ {
+ if (idx != -1)
+ {
+ m_Signals.RemoveAt(idx);
+ m_Events.RemoveAt(idx);
+ }
+ }
+
+ public void Remove(SignalAsset key)
+ {
+ var idx = m_Signals.IndexOf(key);
+ if (idx != -1)
+ {
+ m_Signals.RemoveAt(idx);
+ m_Events.RemoveAt(idx);
+ }
+ }
+
+ public List<SignalAsset> signals
+ {
+ get { return m_Signals; }
+ }
+
+ public List<UnityEvent> events
+ {
+ get { return m_Events; }
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs.meta
new file mode 100644
index 0000000..8d08ff6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Events/Signals/SignalReceiver.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e52de21a22b6dd44c9cc19f810c65059
+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/Extensions.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions.meta
new file mode 100644
index 0000000..d78ad19
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6c61ba0c209bcc74f83e3650039ebdf9
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs
new file mode 100644
index 0000000..87eec1b
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs
@@ -0,0 +1,76 @@
+using System;
+using UnityEngine;
+using UnityEngine.Timeline;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Extension methods for TrackAssets
+ /// </summary>
+ public static class TrackAssetExtensions
+ {
+ /// <summary>
+ /// Gets the GroupTrack this track belongs to.
+ /// </summary>
+ /// <param name="asset">The track asset to find the group of</param>
+ /// <returns>The parent GroupTrack or null if the Track is an override track, or root track.</returns>
+ public static GroupTrack GetGroup(this TrackAsset asset)
+ {
+ if (asset == null)
+ return null;
+
+ return asset.parent as GroupTrack;
+ }
+
+ /// <summary>
+ /// Assigns the track to the specified group track.
+ /// </summary>
+ /// <param name="asset">The track to assign.</param>
+ /// <param name="group">The GroupTrack to assign the track to.</param>
+ /// <remarks>
+ /// Does not support assigning to a group in a different timeline.
+ /// </remarks>
+ public static void SetGroup(this TrackAsset asset, GroupTrack group)
+ {
+ const string undoString = "Reparent";
+
+ if (asset == null || asset == group || asset.parent == group)
+ return;
+
+ if (group != null && asset.timelineAsset != group.timelineAsset)
+ throw new InvalidOperationException("Cannot assign to a group in a different timeline");
+
+
+ TimelineUndo.PushUndo(asset, undoString);
+
+ var timeline = asset.timelineAsset;
+ var parentTrack = asset.parent as TrackAsset;
+ var parentTimeline = asset.parent as TimelineAsset;
+ if (parentTrack != null || parentTimeline != null)
+ {
+ TimelineUndo.PushUndo(asset.parent, undoString);
+ if (parentTimeline != null)
+ {
+ parentTimeline.RemoveTrack(asset);
+ }
+ else
+ {
+ parentTrack.RemoveSubTrack(asset);
+ }
+ }
+
+ if (group == null)
+ {
+ TimelineUndo.PushUndo(timeline, undoString);
+ asset.parent = asset.timelineAsset;
+ timeline.AddTrackInternal(asset);
+ }
+ else
+ {
+ TimelineUndo.PushUndo(group, undoString);
+ group.AddChild(asset);
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs.meta
new file mode 100644
index 0000000..823e94a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Extensions/TrackExtensions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d3721d5c6afa8e545995dfaada328476
+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/GroupTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs
new file mode 100644
index 0000000..a6d8a7d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A group track is a container that allows tracks to be arranged in a hierarchical manner.
+ /// </summary>
+ [Serializable]
+ [TrackClipType(typeof(TrackAsset))]
+ [SupportsChildTracks]
+ public class GroupTrack : TrackAsset
+ {
+ internal override bool CanCompileClips()
+ {
+ return false;
+ }
+
+ /// <inheritdoc />
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get { return PlayableBinding.None; }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs.meta
new file mode 100644
index 0000000..89aac74
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/GroupTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d0fc6f5187a81dc47999eefade6f0935
+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/ILayerable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs
new file mode 100644
index 0000000..ff7d0e4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs
@@ -0,0 +1,20 @@
+using UnityEngine;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Implement this interface on a TrackAsset derived class to support layers
+ /// </summary>
+ public interface ILayerable
+ {
+ /// <summary>
+ /// Creates a mixer that blends track mixers.
+ /// </summary>
+ /// <param name="graph">The graph where the mixer playable will be added.</param>
+ /// <param name="go">The GameObject that requested the graph.</param>
+ /// <param name="inputCount">The number of inputs on the mixer. There should be an input for each playable from each clip.</param>
+ /// <returns>Returns a playable that is used as a mixer. If this method returns Playable.Null, it indicates that a layer mixer is not needed. In this case, a single track mixer blends all playables generated from all layers.</returns>
+ Playable CreateLayerMixer(PlayableGraph graph, GameObject go, int inputCount);
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs.meta
new file mode 100644
index 0000000..b585e7e
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/ILayerable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1dc9fdfe61a6a8749a0f6b89b45e887d
+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.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables.meta
new file mode 100644
index 0000000..a162894
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Playables.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8b7d06780fca6fc4384580d3ebed9219
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
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:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties.meta
new file mode 100644
index 0000000..d06db75
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ff97302ee78d6ad478b433ec557ee303
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1eaacad
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs
@@ -0,0 +1,28 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("UnityEngine.Timeline")]
+[assembly: AssemblyDescription("Unity Timeline")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Unity Technologies")]
+[assembly: AssemblyProduct("UnityEngine.Timeline")]
+[assembly: AssemblyCopyright("Copyright � 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: InternalsVisibleTo("Unity.Timeline.Editor")]
+[assembly: ComVisible(false)]
+#if UNITY_EDITOR // RuntimeEditor version
+[assembly: Guid("844F8153-91DB-42D4-9455-CBF1A7BFC434")]
+#else // Runtime version
+[assembly: Guid("6A10B290-9283-487F-913B-00D94CD3FAF5")]
+#endif
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: InternalsVisibleTo("Assembly-CSharp-testable")]
+[assembly: InternalsVisibleTo("Assembly-CSharp-Editor-testable")]
+[assembly: InternalsVisibleTo("Unity.Timeline.EditorTests")]
+[assembly: InternalsVisibleTo("Unity.Timeline.Tests")]
+[assembly: InternalsVisibleTo("Unity.Timeline.Tests.Common")]
+[assembly: InternalsVisibleTo("Unity.Timeline.Tests.Performance")]
+[assembly: InternalsVisibleTo("Unity.Timeline.Tests.Performance.Editor")]
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs.meta
new file mode 100644
index 0000000..01b8128
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Properties/AssemblyInfo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0bb74b1c097396c49b1691e6a938f814
+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/Scripting.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting.meta
new file mode 100644
index 0000000..fe679ff
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bdb4f6935641b574b984da8dc27cab45
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs
new file mode 100644
index 0000000..e785cbf
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs
@@ -0,0 +1,23 @@
+using System;
+using UnityEngine;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A PlayableTrack is a track whose clips are custom playables.
+ /// </summary>
+ /// <remarks>
+ /// This is a track that can contain PlayableAssets that are found in the project and do not have their own specified track type.
+ /// </remarks>
+ [Serializable]
+ public class PlayableTrack : TrackAsset
+ {
+ /// <inheritdoc />
+ protected override void OnCreateClip(TimelineClip clip)
+ {
+ if (clip.asset != null)
+ clip.displayName = clip.asset.GetType().Name;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs.meta
new file mode 100644
index 0000000..0129ea2
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Scripting/PlayableTrack.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 82cd92ffc29383742932b27ca414c80f
+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/Timeline.deprecated.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs
new file mode 100644
index 0000000..ac2b4c2
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs
@@ -0,0 +1,34 @@
+using System;
+using UnityEngine;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ public partial class TimelineAsset
+ {
+ [Obsolete("MediaType has been deprecated. It is no longer required, and will be removed in a future release.", false)]
+ public enum MediaType
+ {
+ Animation,
+ Audio,
+ Texture = 2,
+ [Obsolete("Use Texture MediaType instead. (UnityUpgradable) -> UnityEngine.Timeline.TimelineAsset/MediaType.Texture", false)] Video = 2,
+ Script,
+ Hybrid,
+ Group
+ }
+ }
+
+ // Defines the type of a track
+ [AttributeUsage(AttributeTargets.Class)]
+ [Obsolete("TrackMediaType has been deprecated. It is no longer required, and will be removed in a future release.", false)]
+ public class TrackMediaType : Attribute
+ {
+ public readonly TimelineAsset.MediaType m_MediaType;
+
+ public TrackMediaType(TimelineAsset.MediaType mt)
+ {
+ m_MediaType = mt;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs.meta
new file mode 100644
index 0000000..cd16af0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Timeline.deprecated.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7748a1d3701ac824ea7f366ba0388f5d
+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/TimelineAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs
new file mode 100644
index 0000000..ca2572e
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs
@@ -0,0 +1,455 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A PlayableAsset that represents a timeline.
+ /// </summary>
+ [ExcludeFromPreset]
+ [Serializable]
+ public partial class TimelineAsset : PlayableAsset, ISerializationCallbackReceiver, ITimelineClipAsset, IPropertyPreview
+ {
+ /// <summary>
+ /// How the duration of the timeline is determined.
+ /// </summary>
+ public enum DurationMode
+ {
+ /// <summary>
+ /// The duration of the timeline is determined based on the clips present.
+ /// </summary>
+ BasedOnClips,
+ /// <summary>
+ /// The duration of the timeline is a fixed length.
+ /// </summary>
+ FixedLength
+ }
+
+ /// <summary>
+ /// Properties of the timeline that are used by the editor
+ /// </summary>
+ [Serializable]
+ public class EditorSettings
+ {
+ internal static readonly float kMinFps = (float)TimeUtility.kFrameRateEpsilon;
+ internal static readonly float kMaxFps = 1000.0f;
+ internal static readonly float kDefaultFps = 60.0f;
+ [HideInInspector, SerializeField] float m_Framerate = kDefaultFps;
+
+ /// <summary>
+ /// The frames per second used for snapping and time ruler display
+ /// </summary>
+ public float fps
+ {
+ get
+ {
+ return m_Framerate;
+ }
+ set
+ {
+ m_Framerate = GetValidFramerate(value);
+ }
+ }
+ }
+
+ [HideInInspector, SerializeField] List<ScriptableObject> m_Tracks;
+ [HideInInspector, SerializeField] double m_FixedDuration; // only applied if duration mode is Fixed
+ [HideInInspector, NonSerialized] TrackAsset[] m_CacheOutputTracks;
+ [HideInInspector, NonSerialized] List<TrackAsset> m_CacheRootTracks;
+ [HideInInspector, NonSerialized] List<TrackAsset> m_CacheFlattenedTracks;
+ [HideInInspector, SerializeField] EditorSettings m_EditorSettings = new EditorSettings();
+ [SerializeField] DurationMode m_DurationMode;
+
+ [HideInInspector, SerializeField] MarkerTrack m_MarkerTrack;
+
+ /// <summary>
+ /// Settings used by timeline for editing purposes
+ /// </summary>
+ public EditorSettings editorSettings
+ {
+ get { return m_EditorSettings; }
+ }
+
+ /// <summary>
+ /// The length, in seconds, of the timeline
+ /// </summary>
+ public override double duration
+ {
+ get
+ {
+ // @todo cache this value when rebuilt
+ if (m_DurationMode == DurationMode.BasedOnClips)
+ return CalculateDuration();
+
+ return m_FixedDuration;
+ }
+ }
+
+ /// <summary>
+ /// The length of the timeline when durationMode is set to fixed length.
+ /// </summary>
+ public double fixedDuration
+ {
+ get
+ {
+ DiscreteTime discreteDuration = (DiscreteTime)m_FixedDuration;
+ if (discreteDuration <= 0)
+ return 0.0;
+
+ //avoid having no clip evaluated at the end by removing a tick from the total duration
+ return (double)discreteDuration.OneTickBefore();
+ }
+ set { m_FixedDuration = Math.Max(0.0, value); }
+ }
+
+ /// <summary>
+ /// The mode used to determine the duration of the Timeline
+ /// </summary>
+ public DurationMode durationMode
+ {
+ get { return m_DurationMode; }
+ set { m_DurationMode = value; }
+ }
+
+ /// <summary>
+ /// A description of the PlayableOutputs that will be created by the timeline when instantiated.
+ /// </summary>
+ /// <remarks>
+ /// Each track will create an PlayableOutput
+ /// </remarks>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get
+ {
+ foreach (var outputTracks in GetOutputTracks())
+ foreach (var output in outputTracks.outputs)
+ yield return output;
+ }
+ }
+
+ public ClipCaps clipCaps
+ {
+ get
+ {
+ var caps = ClipCaps.All;
+ foreach (var track in GetRootTracks())
+ {
+ foreach (var clip in track.clips)
+ caps &= clip.clipCaps;
+ }
+ return caps;
+ }
+ }
+
+ /// <summary>
+ /// Returns the the number of output tracks in the Timeline.
+ /// </summary>
+ /// <remarks>
+ /// An output track is a track the generates a PlayableOutput. In general, an output track is any track that is not a GroupTrack, a subtrack, or override track.
+ /// </remarks>
+ public int outputTrackCount
+ {
+ get
+ {
+ UpdateOutputTrackCache(); // updates the cache if necessary
+ return m_CacheOutputTracks.Length;
+ }
+ }
+
+ /// <summary>
+ /// Returns the number of tracks at the root level of the timeline.
+ /// </summary>
+ /// <remarks>
+ /// A root track refers to all tracks that occur at the root of the timeline. These are the outmost level GroupTracks, and output tracks that do not belong to any group
+ /// </remarks>
+ public int rootTrackCount
+ {
+ get
+ {
+ UpdateRootTrackCache();
+ return m_CacheRootTracks.Count;
+ }
+ }
+
+ void OnValidate()
+ {
+ editorSettings.fps = GetValidFramerate(editorSettings.fps);
+ }
+
+ static float GetValidFramerate(float framerate)
+ {
+ return Mathf.Clamp(framerate, EditorSettings.kMinFps, EditorSettings.kMaxFps);
+ }
+
+ /// <summary>
+ /// Retrieves at root track at the specified index.
+ /// </summary>
+ /// <param name="index">Index of the root track to get. Must be between 0 and rootTrackCount</param>
+ /// <remarks>
+ /// A root track refers to all tracks that occur at the root of the timeline. These are the outmost level GroupTracks, and output tracks that do not belong to any group.
+ /// </remarks>
+ public TrackAsset GetRootTrack(int index)
+ {
+ UpdateRootTrackCache();
+ return m_CacheRootTracks[index];
+ }
+
+ /// <summary>
+ /// Get an enumerable list of all root tracks.
+ /// </summary>
+ /// <returns>An IEnumerable of all root tracks.</returns>
+ /// <remarks>A root track refers to all tracks that occur at the root of the timeline. These are the outmost level GroupTracks, and output tracks that do not belong to any group.</remarks>
+ public IEnumerable<TrackAsset> GetRootTracks()
+ {
+ UpdateRootTrackCache();
+ return m_CacheRootTracks;
+ }
+
+ /// <summary>
+ /// Retrives the output track from the given index.
+ /// </summary>
+ /// <param name="index">Index of the output track to retrieve. Must be between 0 and outputTrackCount</param>
+ /// <returns>The output track from the given index</returns>
+ public TrackAsset GetOutputTrack(int index)
+ {
+ UpdateOutputTrackCache();
+ return m_CacheOutputTracks[index];
+ }
+
+ /// <summary>
+ /// Gets a list of all output tracks in the Timeline.
+ /// </summary>
+ /// <returns>An IEnumerable of all output tracks</returns>
+ /// <remarks>
+ /// An output track is a track the generates a PlayableOutput. In general, an output track is any track that is not a GroupTrack or subtrack.
+ /// </remarks>
+ public IEnumerable<TrackAsset> GetOutputTracks()
+ {
+ UpdateOutputTrackCache();
+ return m_CacheOutputTracks;
+ }
+
+ void UpdateRootTrackCache()
+ {
+ if (m_CacheRootTracks == null)
+ {
+ if (m_Tracks == null)
+ m_CacheRootTracks = new List<TrackAsset>();
+ else
+ {
+ m_CacheRootTracks = new List<TrackAsset>(m_Tracks.Count);
+ if (markerTrack != null)
+ {
+ m_CacheRootTracks.Add(markerTrack);
+ }
+
+ foreach (var t in m_Tracks)
+ {
+ var trackAsset = t as TrackAsset;
+ if (trackAsset != null)
+ m_CacheRootTracks.Add(trackAsset);
+ }
+ }
+ }
+ }
+
+ void UpdateOutputTrackCache()
+ {
+ if (m_CacheOutputTracks == null)
+ {
+ var outputTracks = new List<TrackAsset>();
+ foreach (var flattenedTrack in flattenedTracks)
+ {
+ if (flattenedTrack != null && flattenedTrack.GetType() != typeof(GroupTrack) && !flattenedTrack.isSubTrack)
+ outputTracks.Add(flattenedTrack);
+ }
+ m_CacheOutputTracks = outputTracks.ToArray();
+ }
+ }
+
+ internal IEnumerable<TrackAsset> flattenedTracks
+ {
+ get
+ {
+ if (m_CacheFlattenedTracks == null)
+ {
+ m_CacheFlattenedTracks = new List<TrackAsset>(m_Tracks.Count * 2);
+ UpdateRootTrackCache();
+
+ m_CacheFlattenedTracks.AddRange(m_CacheRootTracks);
+ for (int i = 0; i < m_CacheRootTracks.Count; i++)
+ {
+ AddSubTracksRecursive(m_CacheRootTracks[i], ref m_CacheFlattenedTracks);
+ }
+ }
+ return m_CacheFlattenedTracks;
+ }
+ }
+
+ /// <summary>
+ /// Gets the marker track for this TimelineAsset.
+ /// </summary>
+ /// <returns>Returns the marker track.</returns>
+ /// <remarks>
+ /// Use <see cref="TrackAsset.GetMarkers"/> to get a list of the markers on the returned track.
+ /// </remarks>
+ public MarkerTrack markerTrack
+ {
+ get { return m_MarkerTrack; }
+ }
+
+ // access to the track list as scriptable object
+ internal List<ScriptableObject> trackObjects
+ {
+ get { return m_Tracks; }
+ }
+
+ internal void AddTrackInternal(TrackAsset track)
+ {
+ m_Tracks.Add(track);
+ track.parent = this;
+ Invalidate();
+ }
+
+ internal void RemoveTrack(TrackAsset track)
+ {
+ m_Tracks.Remove(track);
+ Invalidate();
+ var parentTrack = track.parent as TrackAsset;
+ if (parentTrack != null)
+ {
+ parentTrack.RemoveSubTrack(track);
+ }
+ }
+
+ /// <summary>
+ /// Creates an instance of the timeline
+ /// </summary>
+ /// <param name="graph">PlayableGraph that will own the playable</param>
+ /// <param name="go">The gameobject that triggered the graph build</param>
+ /// <returns>The Root Playable of the Timeline</returns>
+ public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
+ {
+ bool autoRebalanceTree = false;
+ #if UNITY_EDITOR
+ autoRebalanceTree = true;
+ #endif
+
+ // only create outputs if we are not nested
+ bool createOutputs = graph.GetPlayableCount() == 0;
+ var timeline = TimelinePlayable.Create(graph, GetOutputTracks(), go, autoRebalanceTree, createOutputs);
+ timeline.SetPropagateSetTime(true);
+ return timeline.IsValid() ? timeline : Playable.Null;
+ }
+
+ void ISerializationCallbackReceiver.OnBeforeSerialize()
+ {
+ m_Version = k_LatestVersion;
+ }
+
+ // resets cache on an Undo
+ void ISerializationCallbackReceiver.OnAfterDeserialize()
+ {
+ Invalidate(); // resets cache on an Undo
+ if (m_Version < k_LatestVersion)
+ {
+ UpgradeToLatestVersion();
+ }
+ }
+
+ void __internalAwake()
+ {
+ if (m_Tracks == null)
+ m_Tracks = new List<ScriptableObject>();
+
+ // validate the array. DON'T remove Unity null objects, just actual null objects
+ for (int i = m_Tracks.Count - 1; i >= 0; i--)
+ {
+ TrackAsset asset = m_Tracks[i] as TrackAsset;
+ if (asset != null)
+ asset.parent = this;
+#if UNITY_EDITOR
+ object o = m_Tracks[i];
+ if (o == null)
+ {
+ Debug.LogWarning("Empty track found while loading timeline. It will be removed.");
+ m_Tracks.RemoveAt(i);
+ }
+#endif
+ }
+ }
+
+ /// <summary>
+ /// Called by the Timeline Editor to gather properties requiring preview.
+ /// </summary>
+ /// <param name="director">The PlayableDirector invoking the preview</param>
+ /// <param name="driver">PropertyCollector used to gather previewable properties</param>
+ public void GatherProperties(PlayableDirector director, IPropertyCollector driver)
+ {
+ var outputTracks = GetOutputTracks();
+ foreach (var track in outputTracks)
+ {
+ track.GatherProperties(director, driver);
+ }
+ }
+
+ /// <summary>
+ /// Creates a marker track for the TimelineAsset.
+ /// </summary>
+ /// In the editor, the marker track appears under the Timeline ruler.
+ /// <remarks>
+ /// This track is always bound to the GameObject that contains the PlayableDirector component for the current timeline.
+ /// The marker track is created the first time this method is called. If the marker track is already created, this method does nothing.
+ /// </remarks>
+ public void CreateMarkerTrack()
+ {
+ if (m_MarkerTrack == null)
+ {
+ m_MarkerTrack = CreateInstance<MarkerTrack>();
+ TimelineCreateUtilities.SaveAssetIntoObject(m_MarkerTrack, this);
+ m_MarkerTrack.parent = this;
+ m_MarkerTrack.name = "Markers"; // This name will show up in the bindings list if it contains signals
+ Invalidate();
+ }
+ }
+
+ // Invalidates the asset, call this if changing the asset data
+ internal void Invalidate()
+ {
+ m_CacheRootTracks = null;
+ m_CacheOutputTracks = null;
+ m_CacheFlattenedTracks = null;
+ }
+
+ double CalculateDuration()
+ {
+ var discreteDuration = new DiscreteTime(0);
+ foreach (var track in flattenedTracks)
+ {
+ if (track.muted)
+ continue;
+
+ discreteDuration = DiscreteTime.Max(discreteDuration, (DiscreteTime)track.end);
+ }
+
+ if (discreteDuration <= 0)
+ return 0.0;
+
+ //avoid having no clip evaluated at the end by removing a tick from the total duration
+ return (double)discreteDuration.OneTickBefore();
+ }
+
+ static void AddSubTracksRecursive(TrackAsset track, ref List<TrackAsset> allTracks)
+ {
+ if (track == null)
+ return;
+
+ allTracks.AddRange(track.GetChildTracks());
+ foreach (TrackAsset subTrack in track.GetChildTracks())
+ {
+ AddSubTracksRecursive(subTrack, ref allTracks);
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs.meta
new file mode 100644
index 0000000..d4c4836
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: bfda56da833e2384a9677cd3c976a436
+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/TimelineAsset_CreateRemove.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs
new file mode 100644
index 0000000..8727eae
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs
@@ -0,0 +1,255 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Timeline;
+using UnityEngine.Playables;
+using UnityEngineInternal; // for metro type extensions
+
+namespace UnityEngine.Timeline
+{
+ public partial class TimelineAsset
+ {
+ /// <summary>
+ /// Allows you to create a track and add it to the Timeline.
+ /// </summary>
+ /// <param name="type">The type of track to create. Must derive from TrackAsset.</param>
+ /// <param name="parent">Track to parent to. This can be null.</param>
+ /// <param name="name">Name to give the track.</param>
+ /// <returns>The created track.</returns>
+ /// <remarks>
+ /// This method will throw an InvalidOperationException if the parent is not valid. The parent can be any GroupTrack, or a supported parent type of track. For example, this can be used to create override tracks in AnimationTracks.
+ /// </remarks>
+ public TrackAsset CreateTrack(Type type, TrackAsset parent, string name)
+ {
+ if (parent != null && parent.timelineAsset != this)
+ throw new InvalidOperationException("Addtrack cannot parent to a track not in the Timeline");
+
+ if (!typeof(TrackAsset).IsAssignableFrom(type))
+ throw new InvalidOperationException("Supplied type must be a track asset");
+
+ if (parent != null)
+ {
+ if (!TimelineCreateUtilities.ValidateParentTrack(parent, type))
+ throw new InvalidOperationException("Cannot assign a child of type " + type.Name + " to a parent of type " + parent.GetType().Name);
+ }
+
+
+ var actualParent = parent != null ? parent as PlayableAsset : this;
+ TimelineUndo.PushUndo(actualParent, "Create Track");
+
+ var baseName = name;
+ if (string.IsNullOrEmpty(baseName))
+ {
+ baseName = type.Name;
+#if UNITY_EDITOR
+ baseName = UnityEditor.ObjectNames.NicifyVariableName(baseName);
+#endif
+ }
+
+ var trackName = baseName;
+ if (parent != null)
+ trackName = TimelineCreateUtilities.GenerateUniqueActorName(parent.subTracksObjects, baseName);
+ else
+ trackName = TimelineCreateUtilities.GenerateUniqueActorName(trackObjects, baseName);
+
+ TrackAsset newTrack = AllocateTrack(parent, trackName, type);
+ if (newTrack != null)
+ {
+ newTrack.name = trackName;
+ TimelineCreateUtilities.SaveAssetIntoObject(newTrack, actualParent);
+ }
+ return newTrack;
+ }
+
+ /// <summary>
+ /// Creates a track and adds it to the Timeline Asset.
+ /// </summary>
+ /// <param name="parent">Track to parent to. This can be null.</param>
+ /// <param name="trackName">The name of the track being created.</param>
+ /// <typeparam name="T">The type of track being created. The track type must be derived from TrackAsset.</typeparam>
+ /// <returns>Returns the created track.</returns>
+ /// <remarks>
+ /// This method will throw an InvalidOperationException if the parent is not valid. The parent can be any GroupTrack, or a supported parent type of track. For example, this can be used to create override tracks in AnimationTracks.
+ /// </remarks>
+ public T CreateTrack<T>(TrackAsset parent, string trackName) where T : TrackAsset, new()
+ {
+ return (T)CreateTrack(typeof(T), parent, trackName);
+ }
+
+ /// <summary>
+ /// Creates a track and adds it to the Timeline Asset.
+ /// </summary>
+ /// <param name="trackName">The name of the track being created.</param>
+ /// <typeparam name="T">The type of track being created. The track type must be derived from TrackAsset.</typeparam>
+ /// <returns>Returns the created track.</returns>
+ public T CreateTrack<T>(string trackName) where T : TrackAsset, new()
+ {
+ return (T)CreateTrack(typeof(T), null, trackName);
+ }
+
+ /// <summary>
+ /// Creates a track and adds it to the Timeline Asset.
+ /// </summary>
+ /// <typeparam name="T">The type of track being created. The track type must be derived from TrackAsset.</typeparam>
+ /// <returns>Returns the created track.</returns>
+ public T CreateTrack<T>() where T : TrackAsset, new()
+ {
+ return (T)CreateTrack(typeof(T), null, null);
+ }
+
+ /// <summary>
+ /// Delete a clip from this timeline.
+ /// </summary>
+ /// <param name="clip">The clip to delete.</param>
+ /// <returns>Returns true if the removal was successful</returns>
+ /// <remarks>
+ /// This method will delete a clip and any assets owned by the clip.
+ /// </remarks>
+ public bool DeleteClip(TimelineClip clip)
+ {
+ if (clip == null || clip.parentTrack == null)
+ {
+ return false;
+ }
+ if (this != clip.parentTrack.timelineAsset)
+ {
+ Debug.LogError("Cannot delete a clip from this timeline");
+ return false;
+ }
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Delete Clip");
+ if (clip.curves != null)
+ {
+ TimelineUndo.PushDestroyUndo(this, clip.parentTrack, clip.curves, "Delete Curves");
+ }
+
+ // handle wrapped assets
+ if (clip.asset != null)
+ {
+ DeleteRecordedAnimation(clip);
+
+ // TODO -- we should flag assets and owned, instead of this check...
+#if UNITY_EDITOR
+ string path = UnityEditor.AssetDatabase.GetAssetPath(clip.asset);
+ if (path == UnityEditor.AssetDatabase.GetAssetPath(this))
+#endif
+ {
+ TimelineUndo.PushDestroyUndo(this, clip.parentTrack, clip.asset, "Delete Clip Asset");
+ }
+ }
+
+ var clipParentTrack = clip.parentTrack;
+ clipParentTrack.RemoveClip(clip);
+ clipParentTrack.CalculateExtrapolationTimes();
+
+ return true;
+ }
+
+ /// <summary>
+ /// Deletes a track from a timeline, including all clips and subtracks.
+ /// </summary>
+ /// <param name="track">The track to delete. It must be owned by this Timeline.</param>
+ /// <returns>True if the track was deleted successfully.</returns>
+ public bool DeleteTrack(TrackAsset track)
+ {
+ if (track.timelineAsset != this)
+ return false;
+
+ // push before we modify properties
+ TimelineUndo.PushUndo(track, "Delete Track");
+ TimelineUndo.PushUndo(this, "Delete Track");
+
+ TrackAsset parent = track.parent as TrackAsset;
+ if (parent != null)
+ TimelineUndo.PushUndo(parent, "Delete Track");
+
+ var children = track.GetChildTracks();
+ foreach (var child in children)
+ {
+ DeleteTrack(child);
+ }
+
+ DeleteRecordedAnimation(track);
+
+ var clipsToDelete = new List<TimelineClip>(track.clips);
+ foreach (var clip in clipsToDelete)
+ {
+ DeleteClip(clip);
+ }
+ RemoveTrack(track);
+
+ TimelineUndo.PushDestroyUndo(this, this, track, "Delete Track");
+
+ return true;
+ }
+
+ internal void MoveLastTrackBefore(TrackAsset asset)
+ {
+ if (m_Tracks == null || m_Tracks.Count < 2 || asset == null)
+ return;
+
+ var lastTrack = m_Tracks[m_Tracks.Count - 1];
+ if (lastTrack == asset)
+ return;
+
+ for (int i = 0; i < m_Tracks.Count - 1; i++)
+ {
+ if (m_Tracks[i] == asset)
+ {
+ for (int j = m_Tracks.Count - 1; j > i; j--)
+ m_Tracks[j] = m_Tracks[j - 1];
+ m_Tracks[i] = lastTrack;
+ Invalidate();
+ break;
+ }
+ }
+ }
+
+ internal TrackAsset AllocateTrack(TrackAsset trackAssetParent, string trackName, Type trackType)
+ {
+ if (trackAssetParent != null && trackAssetParent.timelineAsset != this)
+ throw new InvalidOperationException("Addtrack cannot parent to a track not in the Timeline");
+
+ if (!typeof(TrackAsset).IsAssignableFrom(trackType))
+ throw new InvalidOperationException("Supplied type must be a track asset");
+
+ var asset = (TrackAsset)CreateInstance(trackType);
+ asset.name = trackName;
+
+ if (trackAssetParent != null)
+ trackAssetParent.AddChild(asset);
+ else
+ AddTrackInternal(asset);
+
+ return asset;
+ }
+
+ void DeleteRecordedAnimation(TrackAsset track)
+ {
+ var animTrack = track as AnimationTrack;
+ if (animTrack != null && animTrack.infiniteClip != null)
+ TimelineUndo.PushDestroyUndo(this, track, animTrack.infiniteClip, "Delete Track");
+
+ if (track.curves != null)
+ TimelineUndo.PushDestroyUndo(this, track, track.curves, "Delete Track Parameters");
+ }
+
+ void DeleteRecordedAnimation(TimelineClip clip)
+ {
+ if (clip == null)
+ return;
+
+ if (clip.curves != null)
+ TimelineUndo.PushDestroyUndo(this, clip.parentTrack, clip.curves, "Delete Clip Parameters");
+
+ if (!clip.recordable)
+ return;
+
+ AnimationPlayableAsset asset = clip.asset as AnimationPlayableAsset;
+ if (asset == null || asset.clip == null)
+ return;
+
+ TimelineUndo.PushDestroyUndo(this, asset, asset.clip, "Delete Recording");
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs.meta
new file mode 100644
index 0000000..76d1df6
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAsset_CreateRemove.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 93665e8b67658804d99c4487228cc050
+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/TimelineAttributes.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs
new file mode 100644
index 0000000..69409fd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs
@@ -0,0 +1,222 @@
+using System;
+using UnityEngine;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Specifies the type of PlayableAsset that a TrackAsset derived class can create clips of.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public class TrackClipTypeAttribute : Attribute
+ {
+ /// <summary>
+ /// The type of the clip class associate with this track
+ /// </summary>
+ public readonly Type inspectedType;
+
+ /// <summary>
+ /// Whether to allow automatic creation of these types.
+ /// </summary>
+ public readonly bool allowAutoCreate; // true will make it show up in menus
+
+ /// <summary>
+ /// </summary>
+ /// <param name="clipClass">The type of the clip class to associate with this track. Must derive from PlayableAsset.</param>
+ public TrackClipTypeAttribute(Type clipClass)
+ {
+ inspectedType = clipClass;
+ allowAutoCreate = true;
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <param name="clipClass">The type of the clip class to associate with this track. Must derive from PlayableAsset.</param>
+ /// <param name="allowAutoCreate">Whether to allow automatic creation of these types. Default value is true.</param>
+ /// <remarks>Setting allowAutoCreate to false will cause Timeline to not show menu items for creating clips of this type.</remarks>
+ public TrackClipTypeAttribute(Type clipClass, bool allowAutoCreate)
+ {
+ inspectedType = clipClass;
+ allowAutoCreate = false;
+ }
+ }
+
+ /// <summary>
+ /// Apply this to a PlayableBehaviour class or field to indicate that it is not animatable.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Class)]
+ public class NotKeyableAttribute : Attribute
+ {
+ }
+
+
+ /// <summary>
+ /// Options for track binding
+ /// </summary>
+ [Flags]
+ public enum TrackBindingFlags
+ {
+ /// <summary>
+ /// No options specified
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Allow automatic creating of component during gameObject drag and drop
+ /// </summary>
+ AllowCreateComponent = 1,
+
+ /// <summary>
+ /// All options specified
+ /// </summary>
+ All = AllowCreateComponent
+ }
+
+ /// <summary>
+ /// Specifies the type of object that should be bound to a TrackAsset.
+ /// </summary>
+ /// <example>
+ /// <code>
+ /// using UnityEngine;
+ /// using UnityEngine.Timeline;
+ /// [TrackBindingType(typeof(Light), TrackBindingFlags.AllowCreateComponent)]
+ /// public class LightTrack : TrackAsset
+ /// {
+ /// }
+ /// </code>
+ /// </example>
+ /// <remarks>
+ /// Use this attribute when creating Custom Tracks to specify the type of object the track requires a binding to.
+ /// </remarks>
+ [AttributeUsage(AttributeTargets.Class)]
+ public class TrackBindingTypeAttribute : Attribute
+ {
+ /// <summary>
+ /// The type of binding for the associate track
+ /// </summary>
+ public readonly Type type;
+
+ /// <summary>
+ /// Options for the the track binding
+ /// </summary>
+ public readonly TrackBindingFlags flags;
+
+ public TrackBindingTypeAttribute(Type type)
+ {
+ this.type = type;
+ this.flags = TrackBindingFlags.All;
+ }
+
+ public TrackBindingTypeAttribute(Type type, TrackBindingFlags flags)
+ {
+ this.type = type;
+ this.flags = flags;
+ }
+ }
+
+ // indicates that child tracks are permitted on a track
+ // internal because not fully supported on custom classes yet
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ class SupportsChildTracksAttribute : Attribute
+ {
+ public readonly Type childType;
+ public readonly int levels;
+
+ public SupportsChildTracksAttribute(Type childType = null, int levels = Int32.MaxValue)
+ {
+ this.childType = childType;
+ this.levels = levels;
+ }
+ }
+
+ // indicates that the type should not be put on a PlayableTrack
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+ class IgnoreOnPlayableTrackAttribute : System.Attribute {}
+
+ // used to flag properties as using a time field (second/frames) display
+ class TimeFieldAttribute : PropertyAttribute
+ {
+ public enum UseEditMode
+ {
+ None,
+ ApplyEditMode
+ }
+ public UseEditMode useEditMode { get; }
+
+ public TimeFieldAttribute(UseEditMode useEditMode = UseEditMode.ApplyEditMode)
+ {
+ this.useEditMode = useEditMode;
+ }
+ }
+
+ /// <summary>
+ /// Use this attribute to hide a class from Timeline menus.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ public class HideInMenuAttribute : Attribute {}
+
+ ///<summary>
+ /// Use this attribute to customize the appearance of a Marker.
+ /// </summary>
+ /// Specify the style to use to draw a Marker.
+ /// <example>
+ /// [CustomStyle("MyStyle")]
+ /// public class MyMarker : UnityEngine.Timeline.Marker {}
+ /// </example>
+ /// How to create a custom style rule:
+ /// 1) Create a 'common.uss' USS file in an Editor folder in a StyleSheets/Extensions folder hierarchy.
+ /// Example of valid folder paths:
+ /// - Assets/Editor/StyleSheets/Extensions
+ /// - Assets/Editor/Markers/StyleSheets/Extensions
+ /// - Assets/Timeline/Editor/MyMarkers/StyleSheets/Extensions
+ /// Rules in 'dark.uss' are used if you use the Pro Skin and rules in 'light.uss' are used otherwise.
+ ///
+ /// 2)In the USS file, create a styling rule to customize the appearance of the marker.
+ /// <example>
+ /// MyStyle
+ /// {
+ /// /* Specify the appearance of the marker in the collapsed state here. */
+ /// }
+ ///
+ /// MyStyle:checked
+ /// {
+ /// /* Specify the appearance of the marker in the expanded state here. */
+ /// }
+ ///
+ /// MyStyle:focused:checked
+ /// {
+ /// /* Specify the appearance of the marker in the selected state here. */
+ /// }
+ /// </example>
+ /// <seealso cref="UnityEngine.Timeline.Marker"/>
+ [AttributeUsage(AttributeTargets.Class)]
+ public class CustomStyleAttribute : Attribute
+ {
+ /// <summary>
+ /// The name of the USS style.
+ /// </summary>
+ public readonly string ussStyle;
+
+ /// <param name="ussStyle">The name of the USS style.</param>
+ public CustomStyleAttribute(string ussStyle)
+ {
+ this.ussStyle = ussStyle;
+ }
+ }
+
+ /// <summary>
+ /// Use this attribute to assign a clip, marker or track to a category in a submenu
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ internal class MenuCategoryAttribute : Attribute
+ {
+ /// <summary>
+ /// The menu name of the category
+ /// </summary>
+ public readonly string category;
+
+ public MenuCategoryAttribute(string category)
+ {
+ this.category = category ?? string.Empty;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs.meta
new file mode 100644
index 0000000..ae5547d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineAttributes.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3e99141cd5dbef844a4338bb87930b89
+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/TimelineClip.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs
new file mode 100644
index 0000000..f1aa05b
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs
@@ -0,0 +1,821 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+using UnityEngine.Serialization;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Implement this interface to support advanced features of timeline clips.
+ /// </summary>
+ public interface ITimelineClipAsset
+ {
+ /// <summary>
+ /// Returns a description of the features supported by clips with PlayableAssets implementing this interface.
+ /// </summary>
+ ClipCaps clipCaps { get; }
+ }
+
+ /// <summary>
+ /// Represents a clip on the timeline.
+ /// </summary>
+ [Serializable]
+ public partial class TimelineClip : ICurvesOwner, ISerializationCallbackReceiver
+ {
+ /// <summary>
+ /// The default capabilities for a clip
+ /// </summary>
+ public static readonly ClipCaps kDefaultClipCaps = ClipCaps.Blending;
+
+ /// <summary>
+ /// The default length of a clip in seconds.
+ /// </summary>
+ public static readonly float kDefaultClipDurationInSeconds = 5;
+
+ /// <summary>
+ /// The minimum timescale allowed on a clip
+ /// </summary>
+ public static readonly double kTimeScaleMin = 1.0 / 1000;
+
+ /// <summary>
+ /// The maximum timescale allowed on a clip
+ /// </summary>
+ public static readonly double kTimeScaleMax = 1000;
+
+ internal static readonly string kDefaultCurvesName = "Clip Parameters";
+
+ internal static readonly double kMinDuration = 1 / 60.0;
+
+ // constant representing the longest possible sequence duration
+ internal static readonly double kMaxTimeValue = 1000000; // more than a week's time, and within numerical precision boundaries
+
+ /// <summary>
+ /// How the clip handles time outside its start and end range.
+ /// </summary>
+ public enum ClipExtrapolation
+ {
+ /// <summary>
+ /// No extrapolation is applied.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Hold the time at the end value of the clip.
+ /// </summary>
+ Hold,
+
+ /// <summary>
+ /// Repeat time values outside the start/end range.
+ /// </summary>
+ Loop,
+
+ /// <summary>
+ /// Repeat time values outside the start/end range, reversing direction at each loop
+ /// </summary>
+ PingPong,
+
+ /// <summary>
+ /// Time values are passed in without modification, extending beyond the clips range
+ /// </summary>
+ Continue
+ };
+
+ /// <summary>
+ /// How blend curves are treated in an overlap
+ /// </summary>
+ public enum BlendCurveMode
+ {
+ /// <summary>
+ /// The curve is normalized against the opposing clip
+ /// </summary>
+ Auto,
+
+ /// <summary>
+ /// The blend curve is fixed.
+ /// </summary>
+ Manual
+ };
+
+ internal TimelineClip(TrackAsset parent)
+ {
+ // parent clip into track
+ parentTrack = parent;
+ }
+
+ [SerializeField] double m_Start;
+ [SerializeField] double m_ClipIn;
+ [SerializeField] Object m_Asset;
+ [SerializeField][FormerlySerializedAs("m_HackDuration")] double m_Duration;
+ [SerializeField] double m_TimeScale = 1.0;
+ [SerializeField] TrackAsset m_ParentTrack;
+
+ // for mixing out scripts - default is no mix out (i.e. flat)
+ [SerializeField] double m_EaseInDuration;
+ [SerializeField] double m_EaseOutDuration;
+
+ // the blend durations override ease in / out durations
+ [SerializeField] double m_BlendInDuration = -1.0f;
+ [SerializeField] double m_BlendOutDuration = -1.0f;
+
+ // doubles as ease in/out and blend in/out curves
+ [SerializeField] AnimationCurve m_MixInCurve;
+ [SerializeField] AnimationCurve m_MixOutCurve;
+
+ [SerializeField] BlendCurveMode m_BlendInCurveMode = BlendCurveMode.Auto;
+ [SerializeField] BlendCurveMode m_BlendOutCurveMode = BlendCurveMode.Auto;
+
+ [SerializeField] List<string> m_ExposedParameterNames;
+ [SerializeField] AnimationClip m_AnimationCurves;
+
+ [SerializeField] bool m_Recordable;
+
+ // extrapolation
+ [SerializeField] ClipExtrapolation m_PostExtrapolationMode;
+ [SerializeField] ClipExtrapolation m_PreExtrapolationMode;
+ [SerializeField] double m_PostExtrapolationTime;
+ [SerializeField] double m_PreExtrapolationTime;
+
+ [SerializeField] string m_DisplayName;
+
+ /// <summary>
+ /// Is the clip being extrapolated before its start time?
+ /// </summary>
+ public bool hasPreExtrapolation
+ {
+ get { return m_PreExtrapolationMode != ClipExtrapolation.None && m_PreExtrapolationTime > 0; }
+ }
+
+ /// <summary>
+ /// Is the clip being extrapolated past its end time?
+ /// </summary>
+ public bool hasPostExtrapolation
+ {
+ get { return m_PostExtrapolationMode != ClipExtrapolation.None && m_PostExtrapolationTime > 0; }
+ }
+
+ /// <summary>
+ /// A speed multiplier for the clip;
+ /// </summary>
+ public double timeScale
+ {
+ get { return clipCaps.HasAny(ClipCaps.SpeedMultiplier) ? Math.Max(kTimeScaleMin, Math.Min(m_TimeScale, kTimeScaleMax)) : 1.0; }
+ set
+ {
+ UpdateDirty(m_TimeScale, value);
+ m_TimeScale = clipCaps.HasAny(ClipCaps.SpeedMultiplier) ? Math.Max(kTimeScaleMin, Math.Min(value, kTimeScaleMax)) : 1.0;
+ }
+ }
+
+ /// <summary>
+ /// The start time, in seconds, of the clip
+ /// </summary>
+ public double start
+ {
+ get { return m_Start; }
+ set
+ {
+ UpdateDirty(value, m_Start);
+ var newValue = Math.Max(SanitizeTimeValue(value, m_Start), 0);
+ if (m_ParentTrack != null && m_Start != newValue)
+ {
+ m_ParentTrack.OnClipMove();
+ }
+ m_Start = newValue;
+ }
+ }
+
+ /// <summary>
+ /// The length, in seconds, of the clip
+ /// </summary>
+ public double duration
+ {
+ get { return m_Duration; }
+ set
+ {
+ UpdateDirty(m_Duration, value);
+ m_Duration = Math.Max(SanitizeTimeValue(value, m_Duration), double.Epsilon);
+ }
+ }
+
+ /// <summary>
+ /// The end time, in seconds of the clip
+ /// </summary>
+ public double end
+ {
+ get { return m_Start + m_Duration; }
+ }
+
+ /// <summary>
+ /// Local offset time of the clip.
+ /// </summary>
+ public double clipIn
+ {
+ get { return clipCaps.HasAny(ClipCaps.ClipIn) ? m_ClipIn : 0; }
+ set
+ {
+ UpdateDirty(m_ClipIn, value);
+ m_ClipIn = clipCaps.HasAny(ClipCaps.ClipIn) ? Math.Max(Math.Min(SanitizeTimeValue(value, m_ClipIn), kMaxTimeValue), 0.0) : 0;
+ }
+ }
+
+ /// <summary>
+ /// The name displayed on the clip
+ /// </summary>
+ public string displayName
+ {
+ get { return m_DisplayName; }
+ set { m_DisplayName = value; }
+ }
+
+
+ /// <summary>
+ /// The length, in seconds, of the PlayableAsset attached to the clip.
+ /// </summary>
+ public double clipAssetDuration
+ {
+ get
+ {
+ var playableAsset = m_Asset as IPlayableAsset;
+ return playableAsset != null ? playableAsset.duration : double.MaxValue;
+ }
+ }
+
+ /// <summary>
+ /// An animation clip containing animated properties of the attached PlayableAsset
+ /// </summary>
+ /// <remarks>
+ /// This is where animated clip properties are stored.
+ /// </remarks>
+ public AnimationClip curves
+ {
+ get { return m_AnimationCurves; }
+ internal set { m_AnimationCurves = value; }
+ }
+
+ string ICurvesOwner.defaultCurvesName
+ {
+ get { return kDefaultCurvesName; }
+ }
+
+ /// <summary>
+ /// Whether this clip contains animated properties for the attached PlayableAsset.
+ /// </summary>
+ /// <remarks>
+ /// This property is false if the curves property is null or if it contains no information.
+ /// </remarks>
+ public bool hasCurves
+ {
+ get { return m_AnimationCurves != null && !m_AnimationCurves.empty; }
+ }
+
+ /// <summary>
+ /// The PlayableAsset attached to the clip.
+ /// </summary>
+ public Object asset
+ {
+ get { return m_Asset; }
+ set { m_Asset = value; }
+ }
+
+ Object ICurvesOwner.assetOwner
+ {
+ get { return parentTrack; }
+ }
+
+ TrackAsset ICurvesOwner.targetTrack
+ {
+ get { return parentTrack; }
+ }
+
+ [Obsolete("underlyingAsset property is obsolete. Use asset property instead", true)]
+ public Object underlyingAsset
+ {
+ get { return null; }
+ set {}
+ }
+
+ /// <summary>
+ /// Returns the TrackAsset to which this clip is attached.
+ /// </summary>
+ public TrackAsset parentTrack
+ {
+ get { return m_ParentTrack; }
+ set
+ {
+ if (m_ParentTrack == value)
+ return;
+
+ if (m_ParentTrack != null)
+ m_ParentTrack.RemoveClip(this);
+
+ m_ParentTrack = value;
+
+ if (m_ParentTrack != null)
+ m_ParentTrack.AddClip(this);
+ }
+ }
+
+ /// <summary>
+ /// The ease in duration of the timeline clip in seconds. This only applies if the start of the clip is not overlapping.
+ /// </summary>
+ public double easeInDuration
+ {
+ get { return clipCaps.HasAny(ClipCaps.Blending) ? Math.Min(Math.Max(m_EaseInDuration, 0), duration * 0.49) : 0; }
+ set { m_EaseInDuration = clipCaps.HasAny(ClipCaps.Blending) ? Math.Max(0, Math.Min(SanitizeTimeValue(value, m_EaseInDuration), duration * 0.49)) : 0; }
+ }
+
+ /// <summary>
+ /// The ease out duration of the timeline clip in seconds. This only applies if the end of the clip is not overlapping.
+ /// </summary>
+ public double easeOutDuration
+ {
+ get { return clipCaps.HasAny(ClipCaps.Blending) ? Math.Min(Math.Max(m_EaseOutDuration, 0), duration * 0.49) : 0; }
+ set { m_EaseOutDuration = clipCaps.HasAny(ClipCaps.Blending) ? Math.Max(0, Math.Min(SanitizeTimeValue(value, m_EaseOutDuration), duration * 0.49)) : 0; }
+ }
+
+ [Obsolete("Use easeOutTime instead (UnityUpgradable) -> easeOutTime", true)]
+ public double eastOutTime
+ {
+ get { return duration - easeOutDuration + m_Start; }
+ }
+
+ /// <summary>
+ /// The time in seconds that the ease out begins
+ /// </summary>
+ public double easeOutTime
+ {
+ get { return duration - easeOutDuration + m_Start; }
+ }
+
+ /// <summary>
+ /// The amount of overlap in seconds on the start of a clip.
+ /// </summary>
+ public double blendInDuration
+ {
+ get { return clipCaps.HasAny(ClipCaps.Blending) ? m_BlendInDuration : 0; }
+ set { m_BlendInDuration = clipCaps.HasAny(ClipCaps.Blending) ? SanitizeTimeValue(value, m_BlendInDuration) : 0; }
+ }
+
+ /// <summary>
+ /// The amount of overlap in seconds at the end of a clip.
+ /// </summary>
+ public double blendOutDuration
+ {
+ get { return clipCaps.HasAny(ClipCaps.Blending) ? m_BlendOutDuration : 0; }
+ set { m_BlendOutDuration = clipCaps.HasAny(ClipCaps.Blending) ? SanitizeTimeValue(value, m_BlendOutDuration) : 0; }
+ }
+
+ /// <summary>
+ /// The mode for calculating the blend curve of the overlap at the start of the clip
+ /// </summary>
+ public BlendCurveMode blendInCurveMode
+ {
+ get { return m_BlendInCurveMode; }
+ set { m_BlendInCurveMode = value; }
+ }
+
+ /// <summary>
+ /// The mode for calculating the blend curve of the overlap at the end of the clip
+ /// </summary>
+ public BlendCurveMode blendOutCurveMode
+ {
+ get { return m_BlendOutCurveMode; }
+ set { m_BlendOutCurveMode = value; }
+ }
+
+ /// <summary>
+ /// Returns whether the clip is blending in
+ /// </summary>
+ public bool hasBlendIn { get { return clipCaps.HasAny(ClipCaps.Blending) && m_BlendInDuration > 0; } }
+
+ /// <summary>
+ /// Returns whether the clip is blending out
+ /// </summary>
+ public bool hasBlendOut { get { return clipCaps.HasAny(ClipCaps.Blending) && m_BlendOutDuration > 0; } }
+
+ /// <summary>
+ /// The animation curve used for calculating weights during an ease in or a blend in.
+ /// </summary>
+ public AnimationCurve mixInCurve
+ {
+ get
+ {
+ // auto fix broken curves
+ if (m_MixInCurve == null || m_MixInCurve.length < 2)
+ m_MixInCurve = GetDefaultMixInCurve();
+
+ return m_MixInCurve;
+ }
+ set { m_MixInCurve = value; }
+ }
+
+ /// <summary>
+ /// The amount of the clip being used for ease or blend in as a percentage
+ /// </summary>
+ public float mixInPercentage
+ {
+ get { return (float)(mixInDuration / duration); }
+ }
+
+ /// <summary>
+ /// The amount of the clip blending or easing in, in seconds
+ /// </summary>
+ public double mixInDuration
+ {
+ get { return hasBlendIn ? blendInDuration : easeInDuration; }
+ }
+
+ /// <summary>
+ /// The animation curve used for calculating weights during an ease out or a blend out.
+ /// </summary>
+ public AnimationCurve mixOutCurve
+ {
+ get
+ {
+ if (m_MixOutCurve == null || m_MixOutCurve.length < 2)
+ m_MixOutCurve = GetDefaultMixOutCurve();
+ return m_MixOutCurve;
+ }
+ set { m_MixOutCurve = value; }
+ }
+
+ /// <summary>
+ /// The time in seconds that an ease out or blend out starts
+ /// </summary>
+ public double mixOutTime
+ {
+ get { return duration - mixOutDuration + m_Start; }
+ }
+
+ /// <summary>
+ /// The amount of the clip blending or easing out, in seconds
+ /// </summary>
+ public double mixOutDuration
+ {
+ get { return hasBlendOut ? blendOutDuration : easeOutDuration; }
+ }
+
+ /// <summary>
+ /// The amount of the clip being used for ease or blend out as a percentage
+ /// </summary>
+ public float mixOutPercentage
+ {
+ get { return (float)(mixOutDuration / duration); }
+ }
+
+ /// <summary>
+ /// Returns whether this clip is recordable in editor
+ /// </summary>
+ public bool recordable
+ {
+ get { return m_Recordable; }
+ internal set { m_Recordable = value; }
+ }
+
+ [Obsolete("exposedParameter is deprecated and will be removed in a future release", true)]
+ public List<string> exposedParameters
+ {
+ get { return m_ExposedParameterNames ?? (m_ExposedParameterNames = new List<string>()); }
+ }
+
+ /// <summary>
+ /// Returns the capabilities supported by this clip.
+ /// </summary>
+ public ClipCaps clipCaps
+ {
+ get
+ {
+ var clipAsset = asset as ITimelineClipAsset;
+ return (clipAsset != null) ? clipAsset.clipCaps : kDefaultClipCaps;
+ }
+ }
+
+ internal int Hash()
+ {
+ return HashUtility.CombineHash(m_Start.GetHashCode(),
+ m_Duration.GetHashCode(),
+ m_TimeScale.GetHashCode(),
+ m_ClipIn.GetHashCode(),
+ ((int)m_PreExtrapolationMode).GetHashCode(),
+ ((int)m_PostExtrapolationMode).GetHashCode());
+ }
+
+ /// <summary>
+ /// Given a time, returns the weight from the mix out
+ /// </summary>
+ /// <param name="time">Time (relative to the timeline)</param>
+ /// <returns></returns>
+ public float EvaluateMixOut(double time)
+ {
+ if (!clipCaps.HasAny(ClipCaps.Blending))
+ return 1.0f;
+
+ if (mixOutDuration > Mathf.Epsilon)
+ {
+ var perc = (float)(time - mixOutTime) / (float)mixOutDuration;
+ perc = Mathf.Clamp01(mixOutCurve.Evaluate(perc));
+ return perc;
+ }
+ return 1.0f;
+ }
+
+ /// <summary>
+ /// Given a time, returns the weight from the mix in
+ /// </summary>
+ /// <param name="time">Time (relative to the timeline)</param>
+ /// <returns></returns>
+ public float EvaluateMixIn(double time)
+ {
+ if (!clipCaps.HasAny(ClipCaps.Blending))
+ return 1.0f;
+
+ if (mixInDuration > Mathf.Epsilon)
+ {
+ var perc = (float)(time - m_Start) / (float)mixInDuration;
+ perc = Mathf.Clamp01(mixInCurve.Evaluate(perc));
+ return perc;
+ }
+ return 1.0f;
+ }
+
+ static AnimationCurve GetDefaultMixInCurve()
+ {
+ return AnimationCurve.EaseInOut(0, 0, 1, 1);
+ }
+
+ static AnimationCurve GetDefaultMixOutCurve()
+ {
+ return AnimationCurve.EaseInOut(0, 1, 1, 0);
+ }
+
+ /// <summary>
+ /// Converts from global time to a clips local time.
+ /// </summary>
+ /// <param name="time">time relative to the timeline</param>
+ /// <returns>
+ /// The local time with extrapolation applied
+ /// </returns>
+ public double ToLocalTime(double time)
+ {
+ if (time < 0)
+ return time;
+
+ // handle Extrapolation
+ if (IsPreExtrapolatedTime(time))
+ time = GetExtrapolatedTime(time - m_Start, m_PreExtrapolationMode, m_Duration);
+ else if (IsPostExtrapolatedTime(time))
+ time = GetExtrapolatedTime(time - m_Start, m_PostExtrapolationMode, m_Duration);
+ else
+ time -= m_Start;
+
+ // handle looping and time scale within the clip
+ time *= timeScale;
+ time += clipIn;
+
+ return time;
+ }
+
+ /// <summary>
+ /// Converts from global time to local time of the clip
+ /// </summary>
+ /// <param name="time">The time relative to the timeline</param>
+ /// <returns>The local time, ignoring any extrapolation or bounds</returns>
+ public double ToLocalTimeUnbound(double time)
+ {
+ return (time - m_Start) * timeScale + clipIn;
+ }
+
+ /// <summary>
+ /// Converts from local time of the clip to global time
+ /// </summary>
+ /// <param name="time">Time relative to the clip</param>
+ /// <returns>The time relative to the timeline</returns>
+ internal double FromLocalTimeUnbound(double time)
+ {
+ return (time - clipIn) / timeScale + m_Start;
+ }
+
+ /// <summary>
+ /// If this contains an animation asset, returns the animation clip attached. Otherwise returns null.
+ /// </summary>
+ public AnimationClip animationClip
+ {
+ get
+ {
+ if (m_Asset == null)
+ return null;
+
+ var playableAsset = m_Asset as AnimationPlayableAsset;
+ return playableAsset != null ? playableAsset.clip : null;
+ }
+ }
+
+ static double SanitizeTimeValue(double value, double defaultValue)
+ {
+ if (double.IsInfinity(value) || double.IsNaN(value))
+ {
+ Debug.LogError("Invalid time value assigned");
+ return defaultValue;
+ }
+
+ return Math.Max(-kMaxTimeValue, Math.Min(kMaxTimeValue, value));
+ }
+
+ /// <summary>
+ /// Returns whether the clip is being extrapolated past the end time.
+ /// </summary>
+ public ClipExtrapolation postExtrapolationMode
+ {
+ get { return clipCaps.HasAny(ClipCaps.Extrapolation) ? m_PostExtrapolationMode : ClipExtrapolation.None; }
+ internal set { m_PostExtrapolationMode = clipCaps.HasAny(ClipCaps.Extrapolation) ? value : ClipExtrapolation.None; }
+ }
+
+ /// <summary>
+ /// Returns whether the clip is being extrapolated before the start time.
+ /// </summary>
+ public ClipExtrapolation preExtrapolationMode
+ {
+ get { return clipCaps.HasAny(ClipCaps.Extrapolation) ? m_PreExtrapolationMode : ClipExtrapolation.None; }
+ internal set { m_PreExtrapolationMode = clipCaps.HasAny(ClipCaps.Extrapolation) ? value : ClipExtrapolation.None; }
+ }
+
+ internal void SetPostExtrapolationTime(double time)
+ {
+ m_PostExtrapolationTime = time;
+ }
+
+ internal void SetPreExtrapolationTime(double time)
+ {
+ m_PreExtrapolationTime = time;
+ }
+
+ /// <summary>
+ /// Given a time, returns whether it falls within the clips extrapolation
+ /// </summary>
+ /// <param name="sequenceTime">The time relative to the timeline</param>
+ public bool IsExtrapolatedTime(double sequenceTime)
+ {
+ return IsPreExtrapolatedTime(sequenceTime) || IsPostExtrapolatedTime(sequenceTime);
+ }
+
+ /// <summary>
+ /// Given a time, returns whether it falls within the clip pre-extrapolation
+ /// </summary>
+ /// <param name="sequenceTime">The time relative to the timeline</param>
+ public bool IsPreExtrapolatedTime(double sequenceTime)
+ {
+ return preExtrapolationMode != ClipExtrapolation.None &&
+ sequenceTime < m_Start && sequenceTime >= m_Start - m_PreExtrapolationTime;
+ }
+
+ /// <summary>
+ /// Given a time, returns whether it falls within the clip post-extrapolation
+ /// </summary>
+ /// <param name="sequenceTime">The time relative to the timeline</param>
+ public bool IsPostExtrapolatedTime(double sequenceTime)
+ {
+ return postExtrapolationMode != ClipExtrapolation.None &&
+ (sequenceTime > end) && (sequenceTime - end < m_PostExtrapolationTime);
+ }
+
+ /// <summary>
+ /// The start time of the clip, accounting for pre-extrapolation
+ /// </summary>
+ public double extrapolatedStart
+ {
+ get
+ {
+ if (m_PreExtrapolationMode != ClipExtrapolation.None)
+ return m_Start - m_PreExtrapolationTime;
+
+ return m_Start;
+ }
+ }
+
+ /// <summary>
+ /// The length of the clip in seconds, including extrapolation.
+ /// </summary>
+ public double extrapolatedDuration
+ {
+ get
+ {
+ double length = m_Duration;
+
+ if (m_PostExtrapolationMode != ClipExtrapolation.None)
+ length += Math.Min(m_PostExtrapolationTime, kMaxTimeValue);
+
+ if (m_PreExtrapolationMode != ClipExtrapolation.None)
+ length += m_PreExtrapolationTime;
+
+ return length;
+ }
+ }
+
+ static double GetExtrapolatedTime(double time, ClipExtrapolation mode, double duration)
+ {
+ if (duration == 0)
+ return 0;
+
+ switch (mode)
+ {
+ case ClipExtrapolation.None:
+ break;
+
+ case ClipExtrapolation.Loop:
+ if (time < 0)
+ time = duration - (-time % duration);
+ else if (time > duration)
+ time %= duration;
+ break;
+
+ case ClipExtrapolation.Hold:
+ if (time < 0)
+ return 0;
+ if (time > duration)
+ return duration;
+ break;
+
+ case ClipExtrapolation.PingPong:
+ if (time < 0)
+ {
+ time = duration * 2 - (-time % (duration * 2));
+ time = duration - Math.Abs(time - duration);
+ }
+ else
+ {
+ time = time % (duration * 2.0);
+ time = duration - Math.Abs(time - duration);
+ }
+ break;
+
+ case ClipExtrapolation.Continue:
+ break;
+ }
+ return time;
+ }
+
+ /// <summary>
+ /// Creates an AnimationClip to store animated properties for the attached PlayableAsset.
+ /// </summary>
+ /// <remarks>
+ /// If curves already exists for this clip, this method produces no result regardless of the
+ /// value specified for curvesClipName.
+ /// </remarks>
+ /// <remarks>
+ /// When used from the editor, this method attempts to save the created curves clip to the TimelineAsset.
+ /// The TimelineAsset must already exist in the AssetDatabase to save the curves clip. If the TimelineAsset
+ /// does not exist, the curves clip is still created but it is not saved.
+ /// </remarks>
+ /// <param name="curvesClipName">
+ /// The name of the AnimationClip to create.
+ /// This method does not ensure unique names. If you want a unique clip name, you must provide one.
+ /// See ObjectNames.GetUniqueName for information on a method that creates unique names.
+ /// </param>
+ public void CreateCurves(string curvesClipName)
+ {
+ if (m_AnimationCurves != null)
+ return;
+
+ m_AnimationCurves = TimelineCreateUtilities.CreateAnimationClipForTrack(string.IsNullOrEmpty(curvesClipName) ? kDefaultCurvesName : curvesClipName, parentTrack, true);
+ }
+
+ void ISerializationCallbackReceiver.OnBeforeSerialize()
+ {
+ m_Version = k_LatestVersion;
+ }
+
+ void ISerializationCallbackReceiver.OnAfterDeserialize()
+ {
+ if (m_Version < k_LatestVersion)
+ {
+ UpgradeToLatestVersion();
+ }
+ }
+
+ /// <summary>
+ /// Outputs a more readable representation of the timeline clip as a string
+ /// </summary>
+ /// <returns></returns>
+ public override string ToString()
+ {
+ return UnityString.Format("{0} ({1:F2}, {2:F2}):{3:F2} | {4}", displayName, start, end, clipIn, parentTrack);
+ }
+
+#if UNITY_EDITOR
+ internal int DirtyIndex { get; private set; }
+ internal void MarkDirty()
+ {
+ DirtyIndex++;
+ }
+
+ void UpdateDirty(double oldValue, double newValue)
+ {
+ if (oldValue != newValue)
+ DirtyIndex++;
+ }
+
+#else
+ void UpdateDirty(double oldValue, double newValue) {}
+#endif
+ };
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs.meta
new file mode 100644
index 0000000..ded129f
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelineClip.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 65f3a4c67e4927a478b7036bae1da0e3
+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/TimelinePlayable.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs
new file mode 100644
index 0000000..f028a7a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs
@@ -0,0 +1,310 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Animations;
+using UnityEngine.Audio;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ // Generic evaluation callback called after all the clips have been processed
+ internal interface ITimelineEvaluateCallback
+ {
+ void Evaluate();
+ }
+
+
+#if UNITY_EDITOR
+ /// <summary>
+ /// This Rebalancer class ensures that the interval tree structures stays balance regardless of whether the intervals inside change.
+ /// </summary>
+ class IntervalTreeRebalancer
+ {
+ private IntervalTree<RuntimeElement> m_Tree;
+ public IntervalTreeRebalancer(IntervalTree<RuntimeElement> tree)
+ {
+ m_Tree = tree;
+ }
+
+ public bool Rebalance()
+ {
+ m_Tree.UpdateIntervals();
+ return m_Tree.dirty;
+ }
+ }
+#endif
+
+ // The TimelinePlayable Playable
+ // This is the actual runtime playable that gets evaluated as part of a playable graph.
+ // It "compiles" a list of tracks into an IntervalTree of Runtime clips.
+ // At each frame, it advances time, then fetches the "intersection: of various time interval
+ // using the interval tree.
+ // Finally, on each intersecting clip, it will calculate each clips' local time, as well as
+ // blend weight and set them accordingly
+
+
+ /// <summary>
+ /// The root Playable generated by timeline.
+ /// </summary>
+ public class TimelinePlayable : PlayableBehaviour
+ {
+ private IntervalTree<RuntimeElement> m_IntervalTree = new IntervalTree<RuntimeElement>();
+ private List<RuntimeElement> m_ActiveClips = new List<RuntimeElement>();
+ private List<RuntimeElement> m_CurrentListOfActiveClips;
+ private int m_ActiveBit = 0;
+
+ private List<ITimelineEvaluateCallback> m_EvaluateCallbacks = new List<ITimelineEvaluateCallback>();
+
+ private Dictionary<TrackAsset, Playable> m_PlayableCache = new Dictionary<TrackAsset, Playable>();
+
+ internal static bool muteAudioScrubbing = true;
+
+#if UNITY_EDITOR
+ private IntervalTreeRebalancer m_Rebalancer;
+#endif
+ /// <summary>
+ /// Creates an instance of a Timeline
+ /// </summary>
+ /// <param name="graph">The playable graph to inject the timeline.</param>
+ /// <param name="tracks">The list of tracks to compile</param>
+ /// <param name="go">The GameObject that initiated the compilation</param>
+ /// <param name="autoRebalance">In the editor, whether the graph should account for the possibility of changing clip times</param>
+ /// <param name="createOutputs">Whether to create PlayableOutputs in the graph</param>
+ /// <returns>A subgraph with the playable containing a TimelinePlayable behaviour as the root</returns>
+ public static ScriptPlayable<TimelinePlayable> Create(PlayableGraph graph, IEnumerable<TrackAsset> tracks, GameObject go, bool autoRebalance, bool createOutputs)
+ {
+ if (tracks == null)
+ throw new ArgumentNullException("Tracks list is null", "tracks");
+
+ if (go == null)
+ throw new ArgumentNullException("GameObject parameter is null", "go");
+
+ var playable = ScriptPlayable<TimelinePlayable>.Create(graph);
+ playable.SetTraversalMode(PlayableTraversalMode.Passthrough);
+ var sequence = playable.GetBehaviour();
+ sequence.Compile(graph, playable, tracks, go, autoRebalance, createOutputs);
+ return playable;
+ }
+
+ /// <summary>
+ /// Compiles the subgraph of this timeline
+ /// </summary>
+ /// <param name="graph">The playable graph to inject the timeline.</param>
+ /// <param name="timelinePlayable"></param>
+ /// <param name="tracks">The list of tracks to compile</param>
+ /// <param name="go">The GameObject that initiated the compilation</param>
+ /// <param name="autoRebalance">In the editor, whether the graph should account for the possibility of changing clip times</param>
+ /// <param name="createOutputs">Whether to create PlayableOutputs in the graph</param>
+ public void Compile(PlayableGraph graph, Playable timelinePlayable, IEnumerable<TrackAsset> tracks, GameObject go, bool autoRebalance, bool createOutputs)
+ {
+ if (tracks == null)
+ throw new ArgumentNullException("Tracks list is null", "tracks");
+
+ if (go == null)
+ throw new ArgumentNullException("GameObject parameter is null", "go");
+
+ var outputTrackList = new List<TrackAsset>(tracks);
+ var maximumNumberOfIntersections = outputTrackList.Count * 2 + outputTrackList.Count; // worse case: 2 overlapping clips per track + each track
+ m_CurrentListOfActiveClips = new List<RuntimeElement>(maximumNumberOfIntersections);
+ m_ActiveClips = new List<RuntimeElement>(maximumNumberOfIntersections);
+
+ m_EvaluateCallbacks.Clear();
+ m_PlayableCache.Clear();
+
+ CompileTrackList(graph, timelinePlayable, outputTrackList, go, createOutputs);
+
+#if UNITY_EDITOR
+ if (autoRebalance)
+ {
+ m_Rebalancer = new IntervalTreeRebalancer(m_IntervalTree);
+ }
+#endif
+ }
+
+ private void CompileTrackList(PlayableGraph graph, Playable timelinePlayable, IEnumerable<TrackAsset> tracks, GameObject go, bool createOutputs)
+ {
+ foreach (var track in tracks)
+ {
+ if (!track.IsCompilable())
+ continue;
+
+ if (!m_PlayableCache.ContainsKey(track))
+ {
+ track.SortClips();
+ CreateTrackPlayable(graph, timelinePlayable, track, go, createOutputs);
+ }
+ }
+ }
+
+ void CreateTrackOutput(PlayableGraph graph, TrackAsset track, GameObject go, Playable playable, int port)
+ {
+ if (track.isSubTrack)
+ return;
+
+ var bindings = track.outputs;
+ foreach (var binding in bindings)
+ {
+ var playableOutput = binding.CreateOutput(graph);
+ playableOutput.SetReferenceObject(binding.sourceObject);
+ playableOutput.SetSourcePlayable(playable, port);
+ playableOutput.SetWeight(1.0f);
+
+ // only apply this on our animation track
+ if (track as AnimationTrack != null)
+ {
+ EvaluateWeightsForAnimationPlayableOutput(track, (AnimationPlayableOutput)playableOutput);
+#if UNITY_EDITOR
+ if (!Application.isPlaying)
+ EvaluateAnimationPreviewUpdateCallback(track, (AnimationPlayableOutput)playableOutput);
+#endif
+ }
+ if (playableOutput.IsPlayableOutputOfType<AudioPlayableOutput>())
+ ((AudioPlayableOutput)playableOutput).SetEvaluateOnSeek(!muteAudioScrubbing);
+
+ // If the track is the timeline marker track, assume binding is the PlayableDirector
+ if (track.timelineAsset.markerTrack == track)
+ {
+ var director = go.GetComponent<PlayableDirector>();
+ playableOutput.SetUserData(director);
+ foreach (var c in go.GetComponents<INotificationReceiver>())
+ {
+ playableOutput.AddNotificationReceiver(c);
+ }
+ }
+ }
+ }
+
+ void EvaluateWeightsForAnimationPlayableOutput(TrackAsset track, AnimationPlayableOutput animOutput)
+ {
+ m_EvaluateCallbacks.Add(new AnimationOutputWeightProcessor(animOutput));
+ }
+
+ void EvaluateAnimationPreviewUpdateCallback(TrackAsset track, AnimationPlayableOutput animOutput)
+ {
+ m_EvaluateCallbacks.Add(new AnimationPreviewUpdateCallback(animOutput));
+ }
+
+ private static Playable CreatePlayableGraph(PlayableGraph graph, TrackAsset asset, GameObject go, IntervalTree<RuntimeElement> tree, Playable timelinePlayable)
+ {
+ return asset.CreatePlayableGraph(graph, go, tree, timelinePlayable);
+ }
+
+ private Playable CreateTrackPlayable(PlayableGraph graph, Playable timelinePlayable, TrackAsset track, GameObject go, bool createOutputs)
+ {
+ if (!track.IsCompilable()) // where parents are not compilable (group tracks)
+ return timelinePlayable;
+
+ Playable playable;
+ if (m_PlayableCache.TryGetValue(track, out playable))
+ return playable;
+
+ if (track.name == "root")
+ return timelinePlayable;
+
+ TrackAsset parentActor = track.parent as TrackAsset;
+ var parentPlayable = parentActor != null ? CreateTrackPlayable(graph, timelinePlayable, parentActor, go, createOutputs) : timelinePlayable;
+ var actorPlayable = CreatePlayableGraph(graph, track, go, m_IntervalTree, timelinePlayable);
+ bool connected = false;
+
+ if (!actorPlayable.IsValid())
+ {
+ // if a track says it's compilable, but returns Playable.Null, that can screw up the whole graph.
+ throw new InvalidOperationException(track.name + "(" + track.GetType() + ") did not produce a valid playable. Use the compilable property to indicate whether the track is valid for processing");
+ }
+
+
+ // Special case for animation tracks
+ if (parentPlayable.IsValid() && actorPlayable.IsValid())
+ {
+ int port = parentPlayable.GetInputCount();
+ parentPlayable.SetInputCount(port + 1);
+ connected = graph.Connect(actorPlayable, 0, parentPlayable, port);
+ parentPlayable.SetInputWeight(port, 1.0f);
+ }
+
+ if (createOutputs && connected)
+ {
+ CreateTrackOutput(graph, track, go, parentPlayable, parentPlayable.GetInputCount() - 1);
+ }
+
+ CacheTrack(track, actorPlayable, connected ? (parentPlayable.GetInputCount() - 1) : -1, parentPlayable);
+ return actorPlayable;
+ }
+
+ /// <summary>
+ /// Overridden to handle synchronizing time on the timeline instance.
+ /// </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 UNITY_EDITOR
+ if (m_Rebalancer != null)
+ m_Rebalancer.Rebalance();
+#endif
+
+ // force seek if we are being evaluated
+ // or if our time has jumped. This is used to
+ // resynchronize
+ Evaluate(playable, info);
+ }
+
+ private void Evaluate(Playable playable, FrameData frameData)
+ {
+ if (m_IntervalTree == null)
+ return;
+
+ double localTime = playable.GetTime();
+ m_ActiveBit = m_ActiveBit == 0 ? 1 : 0;
+
+ m_CurrentListOfActiveClips.Clear();
+ m_IntervalTree.IntersectsWith(DiscreteTime.GetNearestTick(localTime), m_CurrentListOfActiveClips);
+
+ foreach (var c in m_CurrentListOfActiveClips)
+ {
+ c.intervalBit = m_ActiveBit;
+ if (frameData.timeLooped)
+ c.Reset();
+ }
+
+ // all previously active clips having a different intervalBit flag are not
+ // in the current intersection, therefore are considered becoming disabled at this frame
+ var timelineEnd = playable.GetDuration();
+ foreach (var c in m_ActiveClips)
+ {
+ if (c.intervalBit != m_ActiveBit)
+ {
+ var clipEnd = (double)DiscreteTime.FromTicks(c.intervalEnd);
+ var time = frameData.timeLooped ? Math.Min(clipEnd, timelineEnd) : Math.Min(localTime, clipEnd);
+ c.EvaluateAt(time, frameData);
+ c.enable = false;
+ }
+ }
+
+ m_ActiveClips.Clear();
+ // case 998642 - don't use m_ActiveClips.AddRange, as in 4.6 .Net scripting it causes GC allocs
+ for (var a = 0; a < m_CurrentListOfActiveClips.Count; a++)
+ {
+ m_CurrentListOfActiveClips[a].EvaluateAt(localTime, frameData);
+ m_ActiveClips.Add(m_CurrentListOfActiveClips[a]);
+ }
+
+ int count = m_EvaluateCallbacks.Count;
+ for (int i = 0; i < count; i++)
+ {
+ m_EvaluateCallbacks[i].Evaluate();
+ }
+ }
+
+ private void CacheTrack(TrackAsset track, Playable playable, int port, Playable parent)
+ {
+ m_PlayableCache[track] = playable;
+ }
+
+ //necessary to build on AOT platforms
+ static void ForAOTCompilationOnly()
+ {
+ new List<IntervalTree<RuntimeElement>.Entry>();
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs.meta
new file mode 100644
index 0000000..cb373dd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TimelinePlayable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 80b10e1c58509a449a3c5aecc07d4455
+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/TrackAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs
new file mode 100644
index 0000000..cc0f607
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs
@@ -0,0 +1,1264 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using UnityEngine.Animations;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// A PlayableAsset representing a track inside a timeline.
+ /// </summary>
+ [Serializable]
+ [IgnoreOnPlayableTrack]
+ public abstract partial class TrackAsset : PlayableAsset, IPropertyPreview, ICurvesOwner
+ {
+ // Internal caches used to avoid memory allocation during graph construction
+ private struct TransientBuildData
+ {
+ public List<TrackAsset> trackList;
+ public List<TimelineClip> clipList;
+ public List<IMarker> markerList;
+
+ public static TransientBuildData Create()
+ {
+ return new TransientBuildData()
+ {
+ trackList = new List<TrackAsset>(20),
+ clipList = new List<TimelineClip>(500),
+ markerList = new List<IMarker>(100),
+ };
+ }
+
+ public void Clear()
+ {
+ trackList.Clear();
+ clipList.Clear();
+ markerList.Clear();
+ }
+ }
+
+ private static TransientBuildData s_BuildData = TransientBuildData.Create();
+
+ internal const string kDefaultCurvesName = "Track Parameters";
+
+ internal static event Action<TimelineClip, GameObject, Playable> OnClipPlayableCreate;
+ internal static event Action<TrackAsset, GameObject, Playable> OnTrackAnimationPlayableCreate;
+
+ [SerializeField, HideInInspector] bool m_Locked;
+ [SerializeField, HideInInspector] bool m_Muted;
+ [SerializeField, HideInInspector] string m_CustomPlayableFullTypename = string.Empty;
+ [SerializeField, HideInInspector] AnimationClip m_Curves;
+ [SerializeField, HideInInspector] PlayableAsset m_Parent;
+ [SerializeField, HideInInspector] List<ScriptableObject> m_Children;
+
+ [NonSerialized] int m_ItemsHash;
+ [NonSerialized] TimelineClip[] m_ClipsCache;
+
+ DiscreteTime m_Start;
+ DiscreteTime m_End;
+ bool m_CacheSorted;
+ bool? m_SupportsNotifications;
+
+ static TrackAsset[] s_EmptyCache = new TrackAsset[0];
+ IEnumerable<TrackAsset> m_ChildTrackCache;
+
+ static Dictionary<Type, TrackBindingTypeAttribute> s_TrackBindingTypeAttributeCache = new Dictionary<Type, TrackBindingTypeAttribute>();
+
+ [SerializeField, HideInInspector] protected internal List<TimelineClip> m_Clips = new List<TimelineClip>();
+
+ [SerializeField, HideInInspector] MarkerList m_Markers = new MarkerList(0);
+
+#if UNITY_EDITOR
+ internal int DirtyIndex { get; private set; }
+ internal void MarkDirty()
+ {
+ DirtyIndex++;
+ foreach (var clip in GetClips())
+ {
+ if (clip != null)
+ clip.MarkDirty();
+ }
+ }
+
+#endif
+
+ /// <summary>
+ /// The start time, in seconds, of this track
+ /// </summary>
+ public double start
+ {
+ get
+ {
+ UpdateDuration();
+ return (double)m_Start;
+ }
+ }
+
+ /// <summary>
+ /// The end time, in seconds, of this track
+ /// </summary>
+ public double end
+ {
+ get
+ {
+ UpdateDuration();
+ return (double)m_End;
+ }
+ }
+
+ /// <summary>
+ /// The length, in seconds, of this track
+ /// </summary>
+ public sealed override double duration
+ {
+ get
+ {
+ UpdateDuration();
+ return (double)(m_End - m_Start);
+ }
+ }
+
+ /// <summary>
+ /// Whether the track is muted or not.
+ /// </summary>
+ /// <remarks>
+ /// A muted track is excluded from the generated PlayableGraph
+ /// </remarks>
+ public bool muted
+ {
+ get { return m_Muted; }
+ set { m_Muted = value; }
+ }
+
+ /// <summary>
+ /// The muted state of a track.
+ /// </summary>
+ /// <remarks>
+ /// A track is also muted when one of its parent tracks are muted.
+ /// </remarks>
+ public bool mutedInHierarchy
+ {
+ get
+ {
+ if (muted)
+ return true;
+
+ TrackAsset p = this;
+ while (p.parent as TrackAsset != null)
+ {
+ p = (TrackAsset)p.parent;
+ if (p as GroupTrack != null)
+ return p.mutedInHierarchy;
+ }
+
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// The TimelineAsset that this track belongs to.
+ /// </summary>
+ public TimelineAsset timelineAsset
+ {
+ get
+ {
+ var node = this;
+ while (node != null)
+ {
+ if (node.parent == null)
+ return null;
+
+ var seq = node.parent as TimelineAsset;
+ if (seq != null)
+ return seq;
+
+ node = node.parent as TrackAsset;
+ }
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// The owner of this track.
+ /// </summary>
+ /// <remarks>
+ /// If this track is a subtrack, the parent is a TrackAsset. Otherwise the parent is a TimelineAsset.
+ /// </remarks>
+ public PlayableAsset parent
+ {
+ get { return m_Parent; }
+ internal set { m_Parent = value; }
+ }
+
+ /// <summary>
+ /// A list of clips owned by this track
+ /// </summary>
+ /// <returns>Returns an enumerable list of clips owned by the track.</returns>
+ public IEnumerable<TimelineClip> GetClips()
+ {
+ return clips;
+ }
+
+ internal TimelineClip[] clips
+ {
+ get
+ {
+ if (m_Clips == null)
+ m_Clips = new List<TimelineClip>();
+
+ if (m_ClipsCache == null)
+ {
+ m_CacheSorted = false;
+ m_ClipsCache = m_Clips.ToArray();
+ }
+
+ return m_ClipsCache;
+ }
+ }
+
+ /// <summary>
+ /// Whether this track is considered empty.
+ /// </summary>
+ /// <remarks>
+ /// A track is considered empty when it does not contain a TimelineClip, Marker, or Curve.
+ /// </remarks>
+ /// <remarks>
+ /// Empty tracks are not included in the playable graph.
+ /// </remarks>
+ public virtual bool isEmpty
+ {
+ get { return !hasClips && !hasCurves && GetMarkerCount() == 0; }
+ }
+
+ /// <summary>
+ /// Whether this track contains any TimelineClip.
+ /// </summary>
+ public bool hasClips
+ {
+ get { return m_Clips != null && m_Clips.Count != 0; }
+ }
+
+ /// <summary>
+ /// Whether this track contains animated properties for the attached PlayableAsset.
+ /// </summary>
+ /// <remarks>
+ /// This property is false if the curves property is null or if it contains no information.
+ /// </remarks>
+ public bool hasCurves
+ {
+ get { return m_Curves != null && !m_Curves.empty; }
+ }
+
+ /// <summary>
+ /// Returns whether this track is a subtrack
+ /// </summary>
+ public bool isSubTrack
+ {
+ get
+ {
+ var owner = parent as TrackAsset;
+ return owner != null && owner.GetType() == GetType();
+ }
+ }
+
+
+ /// <summary>
+ /// Returns a description of the PlayableOutputs that will be created by this track.
+ /// </summary>
+ public override IEnumerable<PlayableBinding> outputs
+ {
+ get
+ {
+ TrackBindingTypeAttribute attribute;
+ if (!s_TrackBindingTypeAttributeCache.TryGetValue(GetType(), out attribute))
+ {
+ attribute = (TrackBindingTypeAttribute)Attribute.GetCustomAttribute(GetType(), typeof(TrackBindingTypeAttribute));
+ s_TrackBindingTypeAttributeCache.Add(GetType(), attribute);
+ }
+
+ var trackBindingType = attribute != null ? attribute.type : null;
+ yield return ScriptPlayableBinding.Create(name, this, trackBindingType);
+ }
+ }
+
+ /// <summary>
+ /// The list of subtracks or child tracks attached to this track.
+ /// </summary>
+ /// <returns>Returns an enumerable list of child tracks owned directly by this track.</returns>
+ /// <remarks>
+ /// In the case of GroupTracks, this returns all tracks contained in the group. This will return the all subtracks or override tracks, if supported by the track.
+ /// </remarks>
+ public IEnumerable<TrackAsset> GetChildTracks()
+ {
+ UpdateChildTrackCache();
+ return m_ChildTrackCache;
+ }
+
+ internal string customPlayableTypename
+ {
+ get { return m_CustomPlayableFullTypename; }
+ set { m_CustomPlayableFullTypename = value; }
+ }
+
+ /// <summary>
+ /// An animation clip storing animated properties of the attached PlayableAsset
+ /// </summary>
+ public AnimationClip curves
+ {
+ get { return m_Curves; }
+ internal set { m_Curves = value; }
+ }
+
+ string ICurvesOwner.defaultCurvesName
+ {
+ get { return kDefaultCurvesName; }
+ }
+
+ Object ICurvesOwner.asset
+ {
+ get { return this; }
+ }
+
+ Object ICurvesOwner.assetOwner
+ {
+ get { return timelineAsset; }
+ }
+
+ TrackAsset ICurvesOwner.targetTrack
+ {
+ get { return this; }
+ }
+
+ // for UI where we need to detect 'null' objects
+ internal List<ScriptableObject> subTracksObjects
+ {
+ get { return m_Children; }
+ }
+
+ /// <summary>
+ /// The local locked state of the track.
+ /// </summary>
+ /// <remarks>
+ /// Note that locking a track only affects operations in the Timeline Editor. It does not prevent other API calls from changing a track or it's clips.
+ ///
+ /// This returns or sets the local locked state of the track. A track may still be locked for editing because one or more of it's parent tracks in the hierarchy is locked. Use lockedInHierarchy to test if a track is locked because of it's own locked state or because of a parent tracks locked state.
+ /// </remarks>
+ public bool locked
+ {
+ get { return m_Locked; }
+ set { m_Locked = value; }
+ }
+
+ /// <summary>
+ /// The locked state of a track. (RO)
+ /// </summary>
+ /// <remarks>
+ /// Note that locking a track only affects operations in the Timeline Editor. It does not prevent other API calls from changing a track or it's clips.
+ ///
+ /// This indicates whether a track is locked in the Timeline Editor because either it's locked property is enabled or a parent track is locked.
+ /// </remarks>
+ public bool lockedInHierarchy
+ {
+ get
+ {
+ if (locked)
+ return true;
+
+ TrackAsset p = this;
+ while (p.parent as TrackAsset != null)
+ {
+ p = (TrackAsset)p.parent;
+ if (p as GroupTrack != null)
+ return p.lockedInHierarchy;
+ }
+
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Indicates if a track accepts markers that implement <see cref="UnityEngine.Playables.INotification"/>.
+ /// </summary>
+ /// <remarks>
+ /// Only tracks with a bound object of type <see cref="UnityEngine.GameObject"/> or <see cref="UnityEngine.Component"/> can accept notifications.
+ /// </remarks>
+ public bool supportsNotifications
+ {
+ get
+ {
+ if (!m_SupportsNotifications.HasValue)
+ {
+ m_SupportsNotifications = NotificationUtilities.TrackTypeSupportsNotifications(GetType());
+ }
+
+ return m_SupportsNotifications.Value;
+ }
+ }
+
+ void __internalAwake() //do not use OnEnable, since users will want it to initialize their class
+ {
+ if (m_Clips == null)
+ m_Clips = new List<TimelineClip>();
+
+ m_ChildTrackCache = null;
+ if (m_Children == null)
+ m_Children = new List<ScriptableObject>();
+#if UNITY_EDITOR
+ // validate the array. DON'T remove Unity null objects, just actual null objects
+ for (int i = m_Children.Count - 1; i >= 0; i--)
+ {
+ object o = m_Children[i];
+ if (o == null)
+ {
+ Debug.LogWarning("Empty child track found while loading timeline. It will be removed.");
+ m_Children.RemoveAt(i);
+ }
+ }
+#endif
+ }
+
+ /// <summary>
+ /// Creates an AnimationClip to store animated properties for the attached PlayableAsset.
+ /// </summary>
+ /// <remarks>
+ /// If curves already exists for this track, this method produces no result regardless of
+ /// the value specified for curvesClipName.
+ /// </remarks>
+ /// <remarks>
+ /// When used from the editor, this method attempts to save the created curves clip to the TimelineAsset.
+ /// The TimelineAsset must already exist in the AssetDatabase to save the curves clip. If the TimelineAsset
+ /// does not exist, the curves clip is still created but it is not saved.
+ /// </remarks>
+ /// <param name="curvesClipName">
+ /// The name of the AnimationClip to create.
+ /// This method does not ensure unique names. If you want a unique clip name, you must provide one.
+ /// See ObjectNames.GetUniqueName for information on a method that creates unique names.
+ /// </param>
+ public void CreateCurves(string curvesClipName)
+ {
+ if (m_Curves != null)
+ return;
+
+ m_Curves = TimelineCreateUtilities.CreateAnimationClipForTrack(string.IsNullOrEmpty(curvesClipName) ? kDefaultCurvesName : curvesClipName, this, true);
+ }
+
+ /// <summary>
+ /// Creates a mixer used to blend playables generated by clips on the track.
+ /// </summary>
+ /// <param name="graph">The graph to inject playables into</param>
+ /// <param name="go">The GameObject that requested the graph.</param>
+ /// <param name="inputCount">The number of playables from clips that will be inputs to the returned mixer</param>
+ /// <returns>A handle to the [[Playable]] representing the mixer.</returns>
+ /// <remarks>
+ /// Override this method to provide a custom playable for mixing clips on a graph.
+ /// </remarks>
+ public virtual Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
+ {
+ return Playable.Create(graph, inputCount);
+ }
+
+ /// <summary>
+ /// Overrides PlayableAsset.CreatePlayable(). Not used in Timeline.
+ /// </summary>
+ public sealed override Playable CreatePlayable(PlayableGraph graph, GameObject go)
+ {
+ return Playable.Null;
+ }
+
+ /// <summary>
+ /// Creates a TimelineClip on this track.
+ /// </summary>
+ /// <returns>Returns a new TimelineClip that is attached to the track.</returns>
+ /// <remarks>
+ /// The type of the playable asset attached to the clip is determined by TrackClip attributes that decorate the TrackAsset derived class
+ /// </remarks>
+ public TimelineClip CreateDefaultClip()
+ {
+ var trackClipTypeAttributes = GetType().GetCustomAttributes(typeof(TrackClipTypeAttribute), true);
+ Type playableAssetType = null;
+ foreach (var trackClipTypeAttribute in trackClipTypeAttributes)
+ {
+ var attribute = trackClipTypeAttribute as TrackClipTypeAttribute;
+ if (attribute != null && typeof(IPlayableAsset).IsAssignableFrom(attribute.inspectedType) && typeof(ScriptableObject).IsAssignableFrom(attribute.inspectedType))
+ {
+ playableAssetType = attribute.inspectedType;
+ break;
+ }
+ }
+
+ if (playableAssetType == null)
+ {
+ Debug.LogWarning("Cannot create a default clip for type " + GetType());
+ return null;
+ }
+ return CreateAndAddNewClipOfType(playableAssetType);
+ }
+
+ /// <summary>
+ /// Creates a clip on the track with a playable asset attached, whose derived type is specified by T
+ /// </summary>
+ /// <typeparam name="T">A PlayableAsset derived type</typeparam>
+ /// <returns>Returns a TimelineClip whose asset is of type T</returns>
+ /// <remarks>
+ /// Throws an InvalidOperationException if the specified type is not supported by the track.
+ /// Supported types are determined by TrackClip attributes that decorate the TrackAsset derived class
+ /// </remarks>
+ public TimelineClip CreateClip<T>() where T : ScriptableObject, IPlayableAsset
+ {
+ return CreateClip(typeof(T));
+ }
+
+ /// <summary>
+ /// Creates a marker of the requested type, at a specific time, and adds the marker to the current asset.
+ /// </summary>
+ /// <param name="type">The type of marker.</param>
+ /// <param name="time">The time where the marker is created.</param>
+ /// <returns>Returns the instance of the created marker.</returns>
+ /// <remarks>
+ /// All markers that implement IMarker and inherit from <see cref="UnityEngine.ScriptableObject"/> are supported.
+ /// Markers that implement the INotification interface cannot be added to tracks that do not support notifications.
+ /// CreateMarker will throw an <code>InvalidOperationException</code> with tracks that do not support notifications if <code>type</code> implements the INotification interface.
+ /// </remarks>
+ /// <seealso cref="UnityEngine.Timeline.Marker"/>
+ /// <seealso cref="UnityEngine.Timeline.TrackAsset.supportsNotifications"/>
+ public IMarker CreateMarker(Type type, double time)
+ {
+ return m_Markers.CreateMarker(type, time, this);
+ }
+
+ /// <summary>
+ /// Creates a marker of the requested type, at a specific time, and adds the marker to the current asset.
+ /// </summary>
+ /// <param name="time">The time where the marker is created.</param>
+ /// <returns>Returns the instance of the created marker.</returns>
+ /// <remarks>
+ /// All markers that implement IMarker and inherit from <see cref="UnityEngine.ScriptableObject"/> are supported.
+ /// CreateMarker will throw an <code>InvalidOperationException</code> with tracks that do not support notifications if <code>T</code> implements the INotification interface.
+ /// </remarks>
+ /// <seealso cref="UnityEngine.Timeline.Marker"/>
+ /// <seealso cref="UnityEngine.Timeline.TrackAsset.supportsNotifications"/>
+ public T CreateMarker<T>(double time) where T : ScriptableObject, IMarker
+ {
+ return (T)CreateMarker(typeof(T), time);
+ }
+
+ /// <summary>
+ /// Removes a marker from the current asset.
+ /// </summary>
+ /// <param name="marker">The marker instance to be removed.</param>
+ /// <returns>Returns true if the marker instance was successfully removed. Returns false otherwise.</returns>
+ public bool DeleteMarker(IMarker marker)
+ {
+ return m_Markers.Remove(marker);
+ }
+
+ /// <summary>
+ /// Returns an enumerable list of markers on the current asset.
+ /// </summary>
+ /// <returns>The list of markers on the asset.
+ /// </returns>
+ public IEnumerable<IMarker> GetMarkers()
+ {
+ return m_Markers.GetMarkers();
+ }
+
+ /// <summary>
+ /// Returns the number of markers on the current asset.
+ /// </summary>
+ /// <returns>The number of markers.</returns>
+ public int GetMarkerCount()
+ {
+ return m_Markers.Count;
+ }
+
+ /// <summary>
+ /// Returns the marker at a given position, on the current asset.
+ /// </summary>
+ /// <param name="idx">The index of the marker to be returned.</param>
+ /// <returns>The marker.</returns>
+ /// <remarks>The ordering of the markers is not guaranteed.
+ /// </remarks>
+ public IMarker GetMarker(int idx)
+ {
+ return m_Markers[idx];
+ }
+
+ internal TimelineClip CreateClip(System.Type requestedType)
+ {
+ if (ValidateClipType(requestedType))
+ return CreateAndAddNewClipOfType(requestedType);
+
+ throw new InvalidOperationException("Clips of type " + requestedType + " are not permitted on tracks of type " + GetType());
+ }
+
+ internal TimelineClip CreateAndAddNewClipOfType(Type requestedType)
+ {
+ var newClip = CreateClipOfType(requestedType);
+ AddClip(newClip);
+ return newClip;
+ }
+
+ internal TimelineClip CreateClipOfType(Type requestedType)
+ {
+ if (!ValidateClipType(requestedType))
+ throw new System.InvalidOperationException("Clips of type " + requestedType + " are not permitted on tracks of type " + GetType());
+
+ var playableAsset = CreateInstance(requestedType);
+ if (playableAsset == null)
+ {
+ throw new System.InvalidOperationException("Could not create an instance of the ScriptableObject type " + requestedType.Name);
+ }
+ playableAsset.name = requestedType.Name;
+ TimelineCreateUtilities.SaveAssetIntoObject(playableAsset, this);
+ TimelineUndo.RegisterCreatedObjectUndo(playableAsset, "Create Clip");
+
+ return CreateClipFromAsset(playableAsset);
+ }
+
+ /// <summary>
+ /// Creates a timeline clip from an existing playable asset.
+ /// </summary>
+ /// <param name="asset"></param>
+ /// <returns></returns>
+ internal TimelineClip CreateClipFromPlayableAsset(IPlayableAsset asset)
+ {
+ if (asset == null)
+ throw new ArgumentNullException("asset");
+
+ if ((asset as ScriptableObject) == null)
+ throw new System.ArgumentException("CreateClipFromPlayableAsset " + " only supports ScriptableObject-derived Types");
+
+ if (!ValidateClipType(asset.GetType()))
+ throw new System.InvalidOperationException("Clips of type " + asset.GetType() + " are not permitted on tracks of type " + GetType());
+
+ return CreateClipFromAsset(asset as ScriptableObject);
+ }
+
+ private TimelineClip CreateClipFromAsset(ScriptableObject playableAsset)
+ {
+ TimelineUndo.PushUndo(this, "Create Clip");
+
+ var newClip = CreateNewClipContainerInternal();
+ newClip.displayName = playableAsset.name;
+ newClip.asset = playableAsset;
+
+ IPlayableAsset iPlayableAsset = playableAsset as IPlayableAsset;
+ if (iPlayableAsset != null)
+ {
+ var candidateDuration = iPlayableAsset.duration;
+
+ if (!double.IsInfinity(candidateDuration) && candidateDuration > 0)
+ newClip.duration = Math.Min(Math.Max(candidateDuration, TimelineClip.kMinDuration), TimelineClip.kMaxTimeValue);
+ }
+
+ try
+ {
+ OnCreateClip(newClip);
+ }
+ catch (Exception e)
+ {
+ Debug.LogError(e.Message, playableAsset);
+ return null;
+ }
+
+ return newClip;
+ }
+
+ internal IEnumerable<ScriptableObject> GetMarkersRaw()
+ {
+ return m_Markers.GetRawMarkerList();
+ }
+
+ internal void ClearMarkers()
+ {
+ m_Markers.Clear();
+ }
+
+ internal void AddMarker(ScriptableObject e)
+ {
+ m_Markers.Add(e);
+ }
+
+ internal bool DeleteMarkerRaw(ScriptableObject marker)
+ {
+ return m_Markers.Remove(marker, timelineAsset, this);
+ }
+
+ int GetTimeRangeHash()
+ {
+ double start = double.MaxValue, end = double.MinValue;
+ foreach (var marker in GetMarkers())
+ {
+ if (!(marker is INotification))
+ {
+ continue;
+ }
+
+ if (marker.time < start)
+ start = marker.time;
+ if (marker.time > end)
+ end = marker.time;
+ }
+
+ return start.GetHashCode().CombineHash(end.GetHashCode());
+ }
+
+ internal void AddClip(TimelineClip newClip)
+ {
+ if (!m_Clips.Contains(newClip))
+ {
+ m_Clips.Add(newClip);
+ m_ClipsCache = null;
+ }
+ }
+
+ Playable CreateNotificationsPlayable(PlayableGraph graph, Playable mixerPlayable, GameObject go, Playable timelinePlayable)
+ {
+ s_BuildData.markerList.Clear();
+ GatherNotificiations(s_BuildData.markerList);
+ var notificationPlayable = NotificationUtilities.CreateNotificationsPlayable(graph, s_BuildData.markerList, go);
+ if (notificationPlayable.IsValid())
+ {
+ notificationPlayable.GetBehaviour().timeSource = timelinePlayable;
+ if (mixerPlayable.IsValid())
+ {
+ notificationPlayable.SetInputCount(1);
+ graph.Connect(mixerPlayable, 0, notificationPlayable, 0);
+ notificationPlayable.SetInputWeight(mixerPlayable, 1);
+ }
+ }
+
+ return notificationPlayable;
+ }
+
+ internal Playable CreatePlayableGraph(PlayableGraph graph, GameObject go, IntervalTree<RuntimeElement> tree, Playable timelinePlayable)
+ {
+ UpdateDuration();
+ var mixerPlayable = Playable.Null;
+ if (CanCompileClipsRecursive())
+ mixerPlayable = OnCreateClipPlayableGraph(graph, go, tree);
+
+ var notificationsPlayable = CreateNotificationsPlayable(graph, mixerPlayable, go, timelinePlayable);
+ if (!notificationsPlayable.IsValid() && !mixerPlayable.IsValid())
+ {
+ Debug.LogErrorFormat("Track {0} of type {1} has no notifications and returns an invalid mixer Playable", name,
+ GetType().FullName);
+
+ return Playable.Create(graph);
+ }
+
+ return notificationsPlayable.IsValid() ? notificationsPlayable : mixerPlayable;
+ }
+
+ internal virtual Playable CompileClips(PlayableGraph graph, GameObject go, IList<TimelineClip> timelineClips, IntervalTree<RuntimeElement> tree)
+ {
+ var blend = CreateTrackMixer(graph, go, timelineClips.Count);
+ for (var c = 0; c < timelineClips.Count; c++)
+ {
+ var source = CreatePlayable(graph, go, timelineClips[c]);
+ if (source.IsValid())
+ {
+ source.SetDuration(timelineClips[c].duration);
+ var clip = new RuntimeClip(timelineClips[c], source, blend);
+ tree.Add(clip);
+ graph.Connect(source, 0, blend, c);
+ blend.SetInputWeight(c, 0.0f);
+ }
+ }
+ ConfigureTrackAnimation(tree, go, blend);
+ return blend;
+ }
+
+ void GatherCompilableTracks(IList<TrackAsset> tracks)
+ {
+ if (!muted && CanCompileClips())
+ tracks.Add(this);
+
+ foreach (var c in GetChildTracks())
+ {
+ if (c != null)
+ c.GatherCompilableTracks(tracks);
+ }
+ }
+
+ void GatherNotificiations(List<IMarker> markers)
+ {
+ if (!muted && CanCompileNotifications())
+ markers.AddRange(GetMarkers());
+ foreach (var c in GetChildTracks())
+ {
+ if (c != null)
+ c.GatherNotificiations(markers);
+ }
+ }
+
+ internal virtual Playable OnCreateClipPlayableGraph(PlayableGraph graph, GameObject go, IntervalTree<RuntimeElement> tree)
+ {
+ if (tree == null)
+ throw new ArgumentException("IntervalTree argument cannot be null", "tree");
+
+ if (go == null)
+ throw new ArgumentException("GameObject argument cannot be null", "go");
+
+ s_BuildData.Clear();
+ GatherCompilableTracks(s_BuildData.trackList);
+
+ // nothing to compile
+ if (s_BuildData.trackList.Count == 0)
+ return Playable.Null;
+
+ // check if layers are supported
+ Playable layerMixer = Playable.Null;
+ ILayerable layerable = this as ILayerable;
+ if (layerable != null)
+ layerMixer = layerable.CreateLayerMixer(graph, go, s_BuildData.trackList.Count);
+
+ if (layerMixer.IsValid())
+ {
+ for (int i = 0; i < s_BuildData.trackList.Count; i++)
+ {
+ var mixer = s_BuildData.trackList[i].CompileClips(graph, go, s_BuildData.trackList[i].clips, tree);
+ if (mixer.IsValid())
+ {
+ graph.Connect(mixer, 0, layerMixer, i);
+ layerMixer.SetInputWeight(i, 1.0f);
+ }
+ }
+ return layerMixer;
+ }
+
+ // one track compiles. Add track mixer and clips
+ if (s_BuildData.trackList.Count == 1)
+ return s_BuildData.trackList[0].CompileClips(graph, go, s_BuildData.trackList[0].clips, tree);
+
+ // no layer mixer provided. merge down all clips.
+ for (int i = 0; i < s_BuildData.trackList.Count; i++)
+ s_BuildData.clipList.AddRange(s_BuildData.trackList[i].clips);
+
+#if UNITY_EDITOR
+ bool applyWarning = false;
+ for (int i = 0; i < s_BuildData.trackList.Count; i++)
+ applyWarning |= i > 0 && s_BuildData.trackList[i].hasCurves;
+
+ if (applyWarning)
+ Debug.LogWarning("A layered track contains animated fields, but no layer mixer has been provided. Animated fields on layers will be ignored. Override CreateLayerMixer in " + s_BuildData.trackList[0].GetType().Name + " and return a valid playable to support animated fields on layered tracks.");
+#endif
+ // compile all the clips into a single mixer
+ return CompileClips(graph, go, s_BuildData.clipList, tree);
+ }
+
+ internal void ConfigureTrackAnimation(IntervalTree<RuntimeElement> tree, GameObject go, Playable blend)
+ {
+ if (!hasCurves)
+ return;
+
+ blend.SetAnimatedProperties(m_Curves);
+ tree.Add(new InfiniteRuntimeClip(blend));
+
+ if (OnTrackAnimationPlayableCreate != null)
+ OnTrackAnimationPlayableCreate.Invoke(this, go, blend);
+ }
+
+ // sorts clips by start time
+ internal void SortClips()
+ {
+ var clipsAsArray = clips; // will alloc
+ if (!m_CacheSorted)
+ {
+ Array.Sort(clips, (clip1, clip2) => clip1.start.CompareTo(clip2.start));
+ m_CacheSorted = true;
+ }
+ }
+
+ // clears the clips after a clone
+ internal void ClearClipsInternal()
+ {
+ m_Clips = new List<TimelineClip>();
+ m_ClipsCache = null;
+ }
+
+ internal void ClearSubTracksInternal()
+ {
+ m_Children = new List<ScriptableObject>();
+ Invalidate();
+ }
+
+ // called by an owned clip when it moves
+ internal void OnClipMove()
+ {
+ m_CacheSorted = false;
+ }
+
+ internal TimelineClip CreateNewClipContainerInternal()
+ {
+ var clipContainer = new TimelineClip(this);
+ clipContainer.asset = null;
+
+ // position clip at end of sequence
+ var newClipStart = 0.0;
+ for (var a = 0; a < m_Clips.Count - 1; a++)
+ {
+ var clipDuration = m_Clips[a].duration;
+ if (double.IsInfinity(clipDuration))
+ clipDuration = TimelineClip.kDefaultClipDurationInSeconds;
+ newClipStart = Math.Max(newClipStart, m_Clips[a].start + clipDuration);
+ }
+
+ clipContainer.mixInCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
+ clipContainer.mixOutCurve = AnimationCurve.EaseInOut(0, 1, 1, 0);
+ clipContainer.start = newClipStart;
+ clipContainer.duration = TimelineClip.kDefaultClipDurationInSeconds;
+ clipContainer.displayName = "untitled";
+ return clipContainer;
+ }
+
+ internal void AddChild(TrackAsset child)
+ {
+ if (child == null)
+ return;
+
+ m_Children.Add(child);
+ child.parent = this;
+ Invalidate();
+ }
+
+ internal void MoveLastTrackBefore(TrackAsset asset)
+ {
+ if (m_Children == null || m_Children.Count < 2 || asset == null)
+ return;
+
+ var lastTrack = m_Children[m_Children.Count - 1];
+ if (lastTrack == asset)
+ return;
+
+ for (int i = 0; i < m_Children.Count - 1; i++)
+ {
+ if (m_Children[i] == asset)
+ {
+ for (int j = m_Children.Count - 1; j > i; j--)
+ m_Children[j] = m_Children[j - 1];
+ m_Children[i] = lastTrack;
+ Invalidate();
+ break;
+ }
+ }
+ }
+
+ internal bool RemoveSubTrack(TrackAsset child)
+ {
+ if (m_Children.Remove(child))
+ {
+ Invalidate();
+ child.parent = null;
+ return true;
+ }
+ return false;
+ }
+
+ internal void RemoveClip(TimelineClip clip)
+ {
+ m_Clips.Remove(clip);
+ m_ClipsCache = null;
+ }
+
+ // Is this track compilable for the sequence
+ // calculate the time interval that this track will be evaluated in.
+ internal virtual void GetEvaluationTime(out double outStart, out double outDuration)
+ {
+ outStart = double.PositiveInfinity;
+ var outEnd = double.NegativeInfinity;
+
+ if (hasCurves)
+ {
+ outStart = 0.0;
+ outEnd = TimeUtility.GetAnimationClipLength(curves);
+ }
+
+ foreach (var clip in clips)
+ {
+ outStart = Math.Min(clip.start, outStart);
+ outEnd = Math.Max(clip.end, outEnd);
+ }
+
+ if (HasNotifications())
+ {
+ var notificationDuration = GetNotificationDuration();
+ outStart = Math.Min(notificationDuration, outStart);
+ outEnd = Math.Max(notificationDuration, outEnd);
+ }
+
+ if (double.IsInfinity(outStart) || double.IsInfinity(outEnd))
+ outStart = outDuration = 0.0;
+ else
+ outDuration = outEnd - outStart;
+ }
+
+ // calculate the time interval that the sequence will use to determine length.
+ // by default this is the same as the evaluation, but subclasses can have different
+ // behaviour
+ internal virtual void GetSequenceTime(out double outStart, out double outDuration)
+ {
+ GetEvaluationTime(out outStart, out outDuration);
+ }
+
+ /// <summary>
+ /// Called by the Timeline Editor to gather properties requiring preview.
+ /// </summary>
+ /// <param name="director">The PlayableDirector invoking the preview</param>
+ /// <param name="driver">PropertyCollector used to gather previewable properties</param>
+ public virtual void GatherProperties(PlayableDirector director, IPropertyCollector driver)
+ {
+ // only push on game objects if there is a binding. Subtracks
+ // will use objects on the stack
+ var gameObject = GetGameObjectBinding(director);
+ if (gameObject != null)
+ driver.PushActiveGameObject(gameObject);
+
+ if (hasCurves)
+ driver.AddObjectProperties(this, m_Curves);
+
+ foreach (var clip in clips)
+ {
+ if (clip.curves != null && clip.asset != null)
+ driver.AddObjectProperties(clip.asset, clip.curves);
+
+ IPropertyPreview modifier = clip.asset as IPropertyPreview;
+ if (modifier != null)
+ modifier.GatherProperties(director, driver);
+ }
+
+ foreach (var subtrack in GetChildTracks())
+ {
+ if (subtrack != null)
+ subtrack.GatherProperties(director, driver);
+ }
+
+ if (gameObject != null)
+ driver.PopActiveGameObject();
+ }
+
+ internal GameObject GetGameObjectBinding(PlayableDirector director)
+ {
+ if (director == null)
+ return null;
+
+ var binding = director.GetGenericBinding(this);
+
+ var gameObject = binding as GameObject;
+ if (gameObject != null)
+ return gameObject;
+
+ var comp = binding as Component;
+ if (comp != null)
+ return comp.gameObject;
+
+ return null;
+ }
+
+ internal bool ValidateClipType(Type clipType)
+ {
+ var attrs = GetType().GetCustomAttributes(typeof(TrackClipTypeAttribute), true);
+ for (var c = 0; c < attrs.Length; ++c)
+ {
+ var attr = (TrackClipTypeAttribute)attrs[c];
+ if (attr.inspectedType.IsAssignableFrom(clipType))
+ return true;
+ }
+
+ // special case for playable tracks, they accept all clips (in the runtime)
+ return typeof(PlayableTrack).IsAssignableFrom(GetType()) &&
+ typeof(IPlayableAsset).IsAssignableFrom(clipType) &&
+ typeof(ScriptableObject).IsAssignableFrom(clipType);
+ }
+
+ /// <summary>
+ /// Called when a clip is created on a track.
+ /// </summary>
+ /// <param name="clip">The timeline clip added to this track</param>
+ /// <remarks>Use this method to set default values on a timeline clip, or it's PlayableAsset.</remarks>
+ protected virtual void OnCreateClip(TimelineClip clip) {}
+
+ void UpdateDuration()
+ {
+ // check if something changed in the clips that require a re-calculation of the evaluation times.
+ var itemsHash = CalculateItemsHash();
+ if (itemsHash == m_ItemsHash)
+ return;
+ m_ItemsHash = itemsHash;
+
+ double trackStart, trackDuration;
+ GetSequenceTime(out trackStart, out trackDuration);
+
+ m_Start = (DiscreteTime)trackStart;
+ m_End = (DiscreteTime)(trackStart + trackDuration);
+
+ // calculate the extrapolations time.
+ // TODO Extrapolation time should probably be extracted from the SequenceClip so only a track is aware of it.
+ this.CalculateExtrapolationTimes();
+ }
+
+ protected internal virtual int CalculateItemsHash()
+ {
+ return HashUtility.CombineHash(GetClipsHash(), GetAnimationClipHash(m_Curves), GetTimeRangeHash());
+ }
+
+ /// <summary>
+ /// Constructs a Playable from a TimelineClip.
+ /// </summary>
+ /// <param name="graph">PlayableGraph that will own the playable.</param>
+ /// <param name="gameObject">The GameObject that builds the PlayableGraph.</param>
+ /// <param name="clip">The TimelineClip to construct a playable for.</param>
+ /// <returns>A playable that will be set as an input to the Track Mixer playable, or Playable.Null if the clip does not have a valid PlayableAsset</returns>
+ /// <exception cref="ArgumentException">Thrown if the specified PlayableGraph is not valid.</exception>
+ /// <exception cref="ArgumentNullException">Thrown if the specified TimelineClip is not valid.</exception>
+ /// <remarks>
+ /// By default, this method invokes Playable.CreatePlayable, sets animated properties, and sets the speed of the created playable. Override this method to change this default implementation.
+ /// </remarks>
+ protected virtual Playable CreatePlayable(PlayableGraph graph, GameObject gameObject, TimelineClip clip)
+ {
+ if (!graph.IsValid())
+ throw new ArgumentException("graph must be a valid PlayableGraph");
+ if (clip == null)
+ throw new ArgumentNullException("clip");
+
+ var asset = clip.asset as IPlayableAsset;
+ if (asset != null)
+ {
+ var handle = asset.CreatePlayable(graph, gameObject);
+ if (handle.IsValid())
+ {
+ handle.SetAnimatedProperties(clip.curves);
+ handle.SetSpeed(clip.timeScale);
+ if (OnClipPlayableCreate != null)
+ OnClipPlayableCreate(clip, gameObject, handle);
+ }
+ return handle;
+ }
+ return Playable.Null;
+ }
+
+ internal void Invalidate()
+ {
+ m_ChildTrackCache = null;
+ var timeline = timelineAsset;
+ if (timeline != null)
+ {
+ timeline.Invalidate();
+ }
+ }
+
+ internal double GetNotificationDuration()
+ {
+ if (!supportsNotifications)
+ {
+ return 0;
+ }
+
+ var maxTime = 0.0;
+ foreach (var marker in GetMarkers())
+ {
+ if (!(marker is INotification))
+ {
+ continue;
+ }
+ maxTime = Math.Max(maxTime, marker.time);
+ }
+
+ return maxTime;
+ }
+
+ internal virtual bool CanCompileClips()
+ {
+ return hasClips || hasCurves;
+ }
+
+ internal bool IsCompilable()
+ {
+ var isContainer = typeof(GroupTrack).IsAssignableFrom(GetType());
+
+ if (isContainer)
+ return false;
+
+ var ret = !mutedInHierarchy && (CanCompileClips() || CanCompileNotifications());
+ if (!ret)
+ {
+ foreach (var t in GetChildTracks())
+ {
+ if (t.IsCompilable())
+ return true;
+ }
+ }
+
+ return ret;
+ }
+
+ private void UpdateChildTrackCache()
+ {
+ if (m_ChildTrackCache == null)
+ {
+ if (m_Children == null || m_Children.Count == 0)
+ m_ChildTrackCache = s_EmptyCache;
+ else
+ {
+ var childTracks = new List<TrackAsset>(m_Children.Count);
+ for (int i = 0; i < m_Children.Count; i++)
+ {
+ var subTrack = m_Children[i] as TrackAsset;
+ if (subTrack != null)
+ childTracks.Add(subTrack);
+ }
+ m_ChildTrackCache = childTracks;
+ }
+ }
+ }
+
+ internal virtual int Hash()
+ {
+ return clips.Length + (m_Markers.Count << 16);
+ }
+
+ int GetClipsHash()
+ {
+ var hash = 0;
+ foreach (var clip in m_Clips)
+ {
+ hash = hash.CombineHash(clip.Hash());
+ }
+ return hash;
+ }
+
+ protected static int GetAnimationClipHash(AnimationClip clip)
+ {
+ var hash = 0;
+ if (clip != null && !clip.empty)
+ hash = hash.CombineHash(clip.frameRate.GetHashCode())
+ .CombineHash(clip.length.GetHashCode());
+
+ return hash;
+ }
+
+ bool HasNotifications()
+ {
+ return m_Markers.HasNotifications();
+ }
+
+ bool CanCompileNotifications()
+ {
+ return supportsNotifications && m_Markers.HasNotifications();
+ }
+
+ bool CanCompileClipsRecursive()
+ {
+ if (CanCompileClips())
+ return true;
+ foreach (var track in GetChildTracks())
+ {
+ if (track.CanCompileClipsRecursive())
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs.meta
new file mode 100644
index 0000000..06213be
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/TrackAsset.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3ad53269c7421084ab67f804591994e0
+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/Unity.Timeline.asmdef b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef
new file mode 100644
index 0000000..d4d4bbe
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef
@@ -0,0 +1,6 @@
+{
+ "name": "Unity.Timeline",
+ "references": [],
+ "includePlatforms": [],
+ "excludePlatforms": []
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef.meta
new file mode 100644
index 0000000..454c5db
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Unity.Timeline.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: f06555f75b070af458a003d92f9efb00
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities.meta
new file mode 100644
index 0000000..b9c8db0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f8730045d7da0f84cb11c0d868899577
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs
new file mode 100644
index 0000000..b8ab669
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs
@@ -0,0 +1,266 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using UnityEditor;
+
+
+namespace UnityEngine.Timeline
+{
+ static class AnimationPreviewUtilities
+ {
+ private const string k_PosX = "m_LocalPosition.x";
+ private const string k_PosY = "m_LocalPosition.y";
+ private const string k_PosZ = "m_LocalPosition.z";
+ private const string k_RotX = "m_LocalRotation.x";
+ private const string k_RotY = "m_LocalRotation.y";
+ private const string k_RotZ = "m_LocalRotation.z";
+ private const string k_RotW = "m_LocalRotation.w";
+ private const string k_ScaleX = "m_LocalScale.x";
+ private const string k_ScaleY = "m_LocalScale.y";
+ private const string k_ScaleZ = "m_LocalScale.z";
+ private const string k_EulerAnglesRaw = "localEulerAnglesRaw";
+ private const string k_EulerHint = "m_LocalEulerAnglesHint";
+ private const string k_Pos = "m_LocalPosition";
+ private const string k_Rot = "m_LocalRotation";
+ private const string k_MotionT = "MotionT";
+ private const string k_MotionQ = "MotionQ";
+ private const string k_RootT = "RootT";
+ private const string k_RootQ = "RootQ";
+
+
+ internal class EditorCurveBindingComparer : IEqualityComparer<EditorCurveBinding>
+ {
+ public bool Equals(EditorCurveBinding x, EditorCurveBinding y) { return x.path.Equals(y.path) && x.type == y.type && x.propertyName == y.propertyName; }
+ public int GetHashCode(EditorCurveBinding obj)
+ {
+ return obj.propertyName.GetHashCode() ^ obj.path.GetHashCode();
+ }
+
+ public static readonly EditorCurveBindingComparer Instance = new EditorCurveBindingComparer();
+ }
+
+ // a dictionary is faster than a hashset, because the capacity can be pre-set
+ private static readonly Dictionary<EditorCurveBinding, int> s_CurveSet = new Dictionary<EditorCurveBinding, int>(10000, EditorCurveBindingComparer.Instance);
+ private static readonly AnimatorBindingCache s_BindingCache = new AnimatorBindingCache();
+
+ public static void ClearCaches()
+ {
+ s_BindingCache.Clear();
+ s_CurveSet.Clear();
+ }
+
+ public static EditorCurveBinding[] GetBindings(GameObject animatorRoot, IEnumerable<AnimationClip> clips)
+ {
+ s_CurveSet.Clear();
+ foreach (var clip in clips)
+ {
+ AddBindings(s_BindingCache.GetCurveBindings(clip));
+ }
+
+ // if we have a transform binding, bind the entire skeleton
+ if (NeedsSkeletonBindings(s_CurveSet.Keys))
+ AddBindings(s_BindingCache.GetAnimatorBindings(animatorRoot));
+
+ var bindings = new EditorCurveBinding[s_CurveSet.Keys.Count];
+ s_CurveSet.Keys.CopyTo(bindings, 0);
+ return bindings;
+ }
+
+ public static void PreviewFromCurves(GameObject animatorRoot, IEnumerable<EditorCurveBinding> keys)
+ {
+ if (!AnimationMode.InAnimationMode())
+ return;
+
+ var avatarRoot = GetAvatarRoot(animatorRoot);
+ foreach (var binding in keys)
+ {
+ if (IsAvatarBinding(binding) || IsEuler(binding))
+ continue;
+
+ bool isTransform = typeof(Transform).IsAssignableFrom(binding.type);
+ if (isTransform && binding.propertyName == AnimatorBindingCache.TRPlaceHolder)
+ AddTRBinding(animatorRoot, binding);
+ else if (isTransform && binding.propertyName == AnimatorBindingCache.ScalePlaceholder)
+ AddScaleBinding(animatorRoot, binding);
+ else
+ AnimationMode.AddEditorCurveBinding(avatarRoot, binding);
+ }
+ }
+
+ public static AnimationClip CreateDefaultClip(GameObject animatorRoot, IEnumerable<EditorCurveBinding> keys)
+ {
+ AnimationClip animClip = new AnimationClip() { name = "DefaultPose" };
+ var keyFrames = new[] {new Keyframe(0, 0)};
+ var curve = new AnimationCurve(keyFrames);
+ bool rootMotion = false;
+ var avatarRoot = GetAvatarRoot(animatorRoot);
+
+ foreach (var binding in keys)
+ {
+ if (IsRootMotion(binding))
+ {
+ rootMotion = true;
+ continue;
+ }
+
+ if (typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName == AnimatorBindingCache.TRPlaceHolder)
+ {
+ if (string.IsNullOrEmpty(binding.path))
+ rootMotion = true;
+ else
+ {
+ var transform = animatorRoot.transform.Find(binding.path);
+ if (transform != null)
+ {
+ var pos = transform.localPosition;
+ var rot = transform.localRotation;
+ animClip.SetCurve(binding.path, typeof(Transform), k_PosX, SetZeroKey(curve, keyFrames, pos.x));
+ animClip.SetCurve(binding.path, typeof(Transform), k_PosY, SetZeroKey(curve, keyFrames, pos.y));
+ animClip.SetCurve(binding.path, typeof(Transform), k_PosZ, SetZeroKey(curve, keyFrames, pos.z));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotX, SetZeroKey(curve, keyFrames, rot.x));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotY, SetZeroKey(curve, keyFrames, rot.y));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotZ, SetZeroKey(curve, keyFrames, rot.z));
+ animClip.SetCurve(binding.path, typeof(Transform), k_RotW, SetZeroKey(curve, keyFrames, rot.w));
+ }
+ }
+
+ continue;
+ }
+
+ if (typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName == AnimatorBindingCache.ScalePlaceholder)
+ {
+ var transform = animatorRoot.transform.Find(binding.path);
+ if (transform != null)
+ {
+ var scale = transform.localScale;
+ animClip.SetCurve(binding.path, typeof(Transform), k_ScaleX, SetZeroKey(curve, keyFrames, scale.x));
+ animClip.SetCurve(binding.path, typeof(Transform), k_ScaleY, SetZeroKey(curve, keyFrames, scale.y));
+ animClip.SetCurve(binding.path, typeof(Transform), k_ScaleZ, SetZeroKey(curve, keyFrames, scale.z));
+ }
+
+ continue;
+ }
+
+ // Not setting curves through AnimationUtility.SetEditorCurve to avoid reentrant
+ // onCurveWasModified calls in timeline. This means we don't get sprite curves
+ // in the default clip right now.
+ if (IsAvatarBinding(binding) || IsEulerHint(binding) || binding.isPPtrCurve)
+ continue;
+
+ float floatValue;
+ AnimationUtility.GetFloatValue(avatarRoot, binding, out floatValue);
+ animClip.SetCurve(binding.path, binding.type, binding.propertyName, SetZeroKey(curve, keyFrames, floatValue));
+ }
+
+ // add root motion explicitly.
+ if (rootMotion)
+ {
+ var pos = Vector3.zero; // the appropriate root motion offsets are applied by timeline
+ var rot = Quaternion.identity;
+ animClip.SetCurve(string.Empty, typeof(Transform), k_PosX, SetZeroKey(curve, keyFrames, pos.x));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_PosY, SetZeroKey(curve, keyFrames, pos.y));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_PosZ, SetZeroKey(curve, keyFrames, pos.z));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotX, SetZeroKey(curve, keyFrames, rot.x));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotY, SetZeroKey(curve, keyFrames, rot.y));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotZ, SetZeroKey(curve, keyFrames, rot.z));
+ animClip.SetCurve(string.Empty, typeof(Transform), k_RotW, SetZeroKey(curve, keyFrames, rot.w));
+ }
+
+ return animClip;
+ }
+
+ public static bool IsRootMotion(EditorCurveBinding binding)
+ {
+ // Root Transform TR.
+ if (typeof(Transform).IsAssignableFrom(binding.type) && string.IsNullOrEmpty(binding.path))
+ {
+ return binding.propertyName.StartsWith(k_Pos) || binding.propertyName.StartsWith(k_Rot);
+ }
+
+ // MotionCurves/RootCurves.
+ if (binding.type == typeof(Animator))
+ {
+ return binding.propertyName.StartsWith(k_MotionT) || binding.propertyName.StartsWith(k_MotionQ) ||
+ binding.propertyName.StartsWith(k_RootT) || binding.propertyName.StartsWith(k_RootQ);
+ }
+
+ return false;
+ }
+
+ private static bool NeedsSkeletonBindings(IEnumerable<EditorCurveBinding> bindings)
+ {
+ foreach (var b in bindings)
+ {
+ if (IsSkeletalBinding(b))
+ return true;
+ }
+
+ return false;
+ }
+
+ private static void AddBindings(IEnumerable<EditorCurveBinding> bindings)
+ {
+ foreach (var b in bindings)
+ {
+ if (!s_CurveSet.ContainsKey(b))
+ s_CurveSet[b] = 1;
+ }
+ }
+
+ private static void AddTRBinding(GameObject root, EditorCurveBinding binding)
+ {
+ // This is faster than AnimationMode.AddTransformTR
+ binding.propertyName = k_PosX; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_PosY; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_PosZ; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotX; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotY; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotZ; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_RotW; AnimationMode.AddEditorCurveBinding(root, binding);
+ }
+
+ private static void AddScaleBinding(GameObject root, EditorCurveBinding binding)
+ {
+ // AnimationMode.AddTransformTRS is slow
+ binding.propertyName = k_ScaleX; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_ScaleY; AnimationMode.AddEditorCurveBinding(root, binding);
+ binding.propertyName = k_ScaleZ; AnimationMode.AddEditorCurveBinding(root, binding);
+ }
+
+ private static bool IsEuler(EditorCurveBinding binding)
+ {
+ return typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName.StartsWith(k_EulerAnglesRaw);
+ }
+
+ private static bool IsAvatarBinding(EditorCurveBinding binding)
+ {
+ return typeof(Animator).IsAssignableFrom(binding.type) && string.IsNullOrEmpty(binding.path);
+ }
+
+ private static bool IsSkeletalBinding(EditorCurveBinding binding)
+ {
+ // skin mesh incorporates blend shapes
+ return typeof(Transform).IsAssignableFrom(binding.type) || typeof(SkinnedMeshRenderer).IsAssignableFrom(binding.type);
+ }
+
+ private static AnimationCurve SetZeroKey(AnimationCurve curve, Keyframe[] keys, float val)
+ {
+ keys[0].value = val;
+ curve.keys = keys;
+ return curve;
+ }
+
+ private static bool IsEulerHint(EditorCurveBinding binding)
+ {
+ return typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName.StartsWith(k_EulerHint);
+ }
+
+ private static GameObject GetAvatarRoot(GameObject animatorRoot)
+ {
+ var animator = animatorRoot.GetComponent<Animator>();
+ if (animator != null && animator.avatarRoot != animatorRoot.transform)
+ return animator.avatarRoot.gameObject;
+ return animatorRoot;
+ }
+ }
+}
+#endif
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta
new file mode 100644
index 0000000..82e3768
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimationPreviewUtilities.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 01da6c5b7c781174d818662ce6f39b8b
+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/Utilities/AnimatorBindingCache.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs
new file mode 100644
index 0000000..53198ea
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs
@@ -0,0 +1,133 @@
+#if UNITY_EDITOR
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using UnityEditor;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Animator to Editor Curve Binding cache. Used to prevent frequent calls to GetAnimatorBindings which can be costly
+ /// </summary>
+ class AnimatorBindingCache
+ {
+ public const string TRPlaceHolder = "TransformTR";
+ public const string ScalePlaceholder = "TransformScale";
+
+ struct AnimatorEntry
+ {
+ public int animatorID;
+ public bool applyRootMotion;
+ public bool humanoid;
+ }
+
+ class AnimatorEntryComparer : IEqualityComparer<AnimatorEntry>
+ {
+ public bool Equals(AnimatorEntry x, AnimatorEntry y) { return x.animatorID == y.animatorID && x.applyRootMotion == y.applyRootMotion && x.humanoid == y.humanoid; }
+ public int GetHashCode(AnimatorEntry obj) { return HashUtility.CombineHash(obj.animatorID, obj.applyRootMotion.GetHashCode(), obj.humanoid.GetHashCode()); }
+ public static readonly AnimatorEntryComparer Instance = new AnimatorEntryComparer();
+ }
+
+ readonly Dictionary<AnimatorEntry, EditorCurveBinding[]> m_AnimatorCache = new Dictionary<AnimatorEntry, EditorCurveBinding[]>(AnimatorEntryComparer.Instance);
+ readonly Dictionary<AnimationClip, EditorCurveBinding[]> m_ClipCache = new Dictionary<AnimationClip, EditorCurveBinding[]>();
+
+ private static readonly EditorCurveBinding[] kEmptyArray = new EditorCurveBinding[0];
+ private static readonly List<EditorCurveBinding> s_BindingScratchPad = new List<EditorCurveBinding>(1000);
+
+ public AnimatorBindingCache()
+ {
+ AnimationUtility.onCurveWasModified += OnCurveWasModified;
+ }
+
+ public EditorCurveBinding[] GetAnimatorBindings(GameObject gameObject)
+ {
+ if (gameObject == null)
+ return kEmptyArray;
+
+ Animator animator = gameObject.GetComponent<Animator>();
+ if (animator == null)
+ return kEmptyArray;
+
+ AnimatorEntry entry = new AnimatorEntry()
+ {
+ animatorID = animator.GetInstanceID(),
+ applyRootMotion = animator.applyRootMotion,
+ humanoid = animator.isHuman
+ };
+
+ EditorCurveBinding[] result = null;
+ if (m_AnimatorCache.TryGetValue(entry, out result))
+ return result;
+
+ s_BindingScratchPad.Clear();
+
+ // Replacement for AnimationMode.GetAnimatorBinding - this is faster and allocates kB instead of MB
+ var transforms = animator.GetComponentsInChildren<Transform>();
+ foreach (var t in transforms)
+ {
+ if (animator.IsBoneTransform(t))
+ s_BindingScratchPad.Add(EditorCurveBinding.FloatCurve(AnimationUtility.CalculateTransformPath(t, animator.transform), typeof(Transform), TRPlaceHolder));
+ }
+
+ var streamBindings = AnimationUtility.GetAnimationStreamBindings(animator.gameObject);
+ UpdateTransformBindings(streamBindings);
+ s_BindingScratchPad.AddRange(streamBindings);
+
+ result = new EditorCurveBinding[s_BindingScratchPad.Count];
+ s_BindingScratchPad.CopyTo(result);
+ m_AnimatorCache[entry] = result;
+ return result;
+ }
+
+ public EditorCurveBinding[] GetCurveBindings(AnimationClip clip)
+ {
+ if (clip == null)
+ return kEmptyArray;
+
+ EditorCurveBinding[] result;
+ if (!m_ClipCache.TryGetValue(clip, out result))
+ {
+ result = AnimationMode.GetCurveBindings(clip);
+ UpdateTransformBindings(result);
+ m_ClipCache[clip] = result;
+ }
+
+ return result;
+ }
+
+ private static void UpdateTransformBindings(EditorCurveBinding[] bindings)
+ {
+ for (int i = 0; i < bindings.Length; i++)
+ {
+ var binding = bindings[i];
+ if (AnimationPreviewUtilities.IsRootMotion(binding))
+ {
+ binding.type = typeof(Transform);
+ binding.propertyName = TRPlaceHolder;
+ }
+ else if (typeof(Transform).IsAssignableFrom(binding.type) && (binding.propertyName.StartsWith("m_LocalRotation.") || binding.propertyName.StartsWith("m_LocalPosition.")))
+ {
+ binding.propertyName = TRPlaceHolder;
+ }
+ else if (typeof(Transform).IsAssignableFrom(binding.type) && binding.propertyName.StartsWith("m_LocalScale."))
+ {
+ binding.propertyName = ScalePlaceholder;
+ }
+ bindings[i] = binding;
+ }
+ }
+
+ public void Clear()
+ {
+ m_AnimatorCache.Clear();
+ m_ClipCache.Clear();
+ }
+
+ void OnCurveWasModified(AnimationClip clip, EditorCurveBinding binding, AnimationUtility.CurveModifiedType modification)
+ {
+ m_ClipCache.Remove(clip);
+ }
+ }
+}
+#endif
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta
new file mode 100644
index 0000000..dc6dc1d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/AnimatorBindingCache.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d0080567f62c3f94cb75b2927a349e22
+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/Utilities/Extrapolation.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs
new file mode 100644
index 0000000..34408c9
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs
@@ -0,0 +1,92 @@
+using System;
+using UnityEngine;
+
+// Extension methods responsible for managing extrapolation time
+namespace UnityEngine.Timeline
+{
+ static class Extrapolation
+ {
+ /// <summary>
+ /// The minimum amount of extrapolation time to apply
+ /// </summary>
+ internal static readonly double kMinExtrapolationTime = TimeUtility.kTimeEpsilon * 1000;
+
+ // Calculates the extrapolation times
+ internal static void CalculateExtrapolationTimes(this TrackAsset asset)
+ {
+ TimelineClip[] clips = asset.clips;
+ if (clips == null || clips.Length == 0)
+ return;
+
+ // extrapolation not supported
+ if (!clips[0].SupportsExtrapolation())
+ return;
+
+ var orderedClips = SortClipsByStartTime(clips);
+ if (orderedClips.Length > 0)
+ {
+ // post extrapolation is the minimum time to the next clip
+ for (int i = 0; i < orderedClips.Length; i++)
+ {
+ double minTime = double.PositiveInfinity;
+ for (int j = 0; j < orderedClips.Length; j++)
+ {
+ if (i == j)
+ continue;
+
+ double deltaTime = orderedClips[j].start - orderedClips[i].end;
+ if (deltaTime >= -TimeUtility.kTimeEpsilon && deltaTime < minTime)
+ minTime = Math.Min(minTime, deltaTime);
+ // check for overlapped clips
+ if (orderedClips[j].start <= orderedClips[i].end && orderedClips[j].end > orderedClips[i].end)
+ minTime = 0;
+ }
+ minTime = minTime <= kMinExtrapolationTime ? 0 : minTime;
+ orderedClips[i].SetPostExtrapolationTime(minTime);
+ }
+
+ // the first clip gets pre-extrapolation, then it's only respected if there is no post extrapolation
+ orderedClips[0].SetPreExtrapolationTime(Math.Max(0, orderedClips[0].start));
+ for (int i = 1; i < orderedClips.Length; i++)
+ {
+ double preTime = 0;
+ int prevClip = -1;
+ for (int j = 0; j < i; j++)
+ {
+ // overlap, no pre-time
+ if (orderedClips[j].end > orderedClips[i].start)
+ {
+ prevClip = -1;
+ preTime = 0;
+ break;
+ }
+
+ double gap = orderedClips[i].start - orderedClips[j].end;
+ if (prevClip == -1 || gap < preTime)
+ {
+ preTime = gap;
+ prevClip = j;
+ }
+ }
+ // check for a post extrapolation time
+ if (prevClip >= 0)
+ {
+ if (orderedClips[prevClip].postExtrapolationMode != TimelineClip.ClipExtrapolation.None)
+ preTime = 0;
+ }
+
+ preTime = preTime <= kMinExtrapolationTime ? 0 : preTime;
+ orderedClips[i].SetPreExtrapolationTime(preTime);
+ }
+ }
+ }
+
+ static TimelineClip[] SortClipsByStartTime(TimelineClip[] clips)
+ {
+ var orderedClips = new TimelineClip[clips.Length];
+ Array.Copy(clips, orderedClips, clips.Length);
+ Array.Sort(orderedClips, (clip1, clip2) => clip1.start.CompareTo(clip2.start));
+ return orderedClips;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta
new file mode 100644
index 0000000..69c90cf
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/Extrapolation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 32535dd294c621e4297fba34b15b1c52
+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/Utilities/HashUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs
new file mode 100644
index 0000000..81fa940
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs
@@ -0,0 +1,51 @@
+namespace UnityEngine.Timeline
+{
+ static class HashUtility
+ {
+ // Note. We could have used "params int[] hashes" but we want to avoid allocating.
+
+ public static int CombineHash(this int h1, int h2)
+ {
+ return h1 ^ (int)(h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); // Similar to c++ boost::hash_combine
+ }
+
+ public static int CombineHash(int h1, int h2, int h3)
+ {
+ return CombineHash(h1, h2).CombineHash(h3);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4)
+ {
+ return CombineHash(h1, h2, h3).CombineHash(h4);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4, int h5)
+ {
+ return CombineHash(h1, h2, h3, h4).CombineHash(h5);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4, int h5, int h6)
+ {
+ return CombineHash(h1, h2, h3, h4, h5).CombineHash(h6);
+ }
+
+ public static int CombineHash(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
+ {
+ return CombineHash(h1, h2, h3, h4, h5, h6).CombineHash(h7);
+ }
+
+ public static int CombineHash(int[] hashes)
+ {
+ if (hashes == null || hashes.Length == 0)
+ return 0;
+
+ var h = hashes[0];
+ for (int i = 1; i < hashes.Length; ++i)
+ {
+ h = CombineHash(h, hashes[i]);
+ }
+
+ return h;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta
new file mode 100644
index 0000000..fec5c19
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/HashUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d0ca7b2e84542bf4ab9987087e8d79ad
+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/Utilities/IPropertyCollector.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs
new file mode 100644
index 0000000..08f991a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs
@@ -0,0 +1,102 @@
+using System.Collections.Generic;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Interface used to inform the Timeline Editor about potential property modifications that may occur while previewing.
+ /// </summary>
+ public interface IPropertyCollector
+ {
+ /// <summary>
+ /// Sets the active game object for subsequent property modifications.
+ /// </summary>
+ /// <param name="gameObject">The GameObject to push.</param>
+ void PushActiveGameObject(GameObject gameObject);
+
+ /// <summary>
+ /// Removes the active GameObject from the modification stack, restoring the previous value.
+ /// </summary>
+ void PopActiveGameObject();
+
+ /// <summary>
+ /// Add properties modified by an animation clip.
+ /// </summary>
+ /// <param name="clip">The animation clip that contains the properties</param>
+ void AddFromClip(AnimationClip clip);
+
+ /// <summary>
+ /// Add property modifications specified by a list of animation clips.
+ /// </summary>
+ /// <param name="clips">The list of animation clips used to determine which property modifications to apply.</param>
+ void AddFromClips(IEnumerable<AnimationClip> clips);
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <typeparam name="T">The type of the component the property exists on</typeparam>
+ /// <remarks>
+ /// This method uses the most recent gameObject from PushActiveGameObject
+ /// </remarks>
+ void AddFromName<T>(string name) where T : Component;
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <remarks>
+ /// This method uses the most recent gameObject from PushActiveGameObject
+ /// </remarks>
+ void AddFromName(string name);
+
+ /// <summary>
+ /// Add property modifications modified by an animation clip.
+ /// </summary>
+ /// <param name="obj">The GameObject where the properties exist</param>
+ /// <param name="clip">The animation clip that contains the properties</param>
+ void AddFromClip(GameObject obj, AnimationClip clip);
+
+ /// <summary>
+ /// Add property modifications specified by a list of animation clips.
+ /// </summary>
+ /// <param name="obj">The gameObject that will be animated</param>
+ /// <param name="clips">The list of animation clips used to determine which property modifications to apply.</param>
+ void AddFromClips(GameObject obj, IEnumerable<AnimationClip> clips);
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <param name="obj">The gameObject where the properties exist</param>
+ /// <typeparam name="T">The type of the component the property exists on</typeparam>>
+ void AddFromName<T>(GameObject obj, string name) where T : Component;
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="obj">The gameObject where the properties exist</param>
+ /// <param name="name">The name of the serialized property</param>
+ void AddFromName(GameObject obj, string name);
+
+ /// <summary>
+ /// Add property modifications using the serialized property name.
+ /// </summary>
+ /// <param name="name">The name of the serialized property</param>
+ /// <param name="component">The component where the properties exist</param>
+ void AddFromName(Component component, string name);
+
+ /// <summary>
+ /// Set all serializable properties on a component to be under preview control.
+ /// </summary>
+ /// <param name="obj">The gameObject where the properties exist</param>
+ /// <param name="component">The component to set in preview mode</param>
+ void AddFromComponent(GameObject obj, Component component);
+
+ /// <summary>
+ /// Add property modifications modified by an animation clip.
+ /// </summary>
+ /// <param name="obj">The Object where the properties exist</param>
+ /// <param name="clip">The animation clip that contains the properties</param>
+ void AddObjectProperties(Object obj, AnimationClip clip);
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta
new file mode 100644
index 0000000..05ecf1d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyCollector.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 66b2b8fd1d9b4bc4c96b07335ad822f3
+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/Utilities/IPropertyPreview.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs
new file mode 100644
index 0000000..b779f15
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs
@@ -0,0 +1,17 @@
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ /// <summary>
+ /// Implement this interface in a PlayableAsset to specify which properties will be modified when Timeline is in preview mode.
+ /// </summary>
+ public interface IPropertyPreview
+ {
+ /// <summary>
+ /// Called by the Timeline Editor to gather properties requiring preview.
+ /// </summary>
+ /// <param name="director">The PlayableDirector invoking the preview</param>
+ /// <param name="driver">PropertyCollector used to gather previewable properties</param>
+ void GatherProperties(PlayableDirector director, IPropertyCollector driver);
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta
new file mode 100644
index 0000000..31806d8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/IPropertyPreview.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b5f0881228e5827438f74e9b7b33c2dc
+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/Utilities/NotificationUtilities.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs
new file mode 100644
index 0000000..41aabce
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ static class NotificationUtilities
+ {
+ public static ScriptPlayable<TimeNotificationBehaviour> CreateNotificationsPlayable(PlayableGraph graph, IEnumerable<IMarker> markers, GameObject go)
+ {
+ var notificationPlayable = ScriptPlayable<TimeNotificationBehaviour>.Null;
+ var director = go.GetComponent<PlayableDirector>();
+ foreach (var e in markers)
+ {
+ var notif = e as INotification;
+ if (notif == null)
+ continue;
+
+ if (notificationPlayable.Equals(ScriptPlayable<TimeNotificationBehaviour>.Null))
+ {
+ notificationPlayable = TimeNotificationBehaviour.Create(graph,
+ director.playableAsset.duration, director.extrapolationMode);
+ }
+
+ var time = (DiscreteTime)e.time;
+ var tlDuration = (DiscreteTime)director.playableAsset.duration;
+ if (time >= tlDuration && time <= tlDuration.OneTickAfter() && tlDuration != 0)
+ {
+ time = tlDuration.OneTickBefore();
+ }
+
+ var notificationOptionProvider = e as INotificationOptionProvider;
+ if (notificationOptionProvider != null)
+ {
+ notificationPlayable.GetBehaviour().AddNotification((double)time, notif, notificationOptionProvider.flags);
+ }
+ else
+ {
+ notificationPlayable.GetBehaviour().AddNotification((double)time, notif);
+ }
+ }
+
+ return notificationPlayable;
+ }
+
+ public static bool TrackTypeSupportsNotifications(Type type)
+ {
+ var binding = (TrackBindingTypeAttribute)Attribute.GetCustomAttribute(type, typeof(TrackBindingTypeAttribute));
+ return binding != null &&
+ (typeof(Component).IsAssignableFrom(binding.type) ||
+ typeof(GameObject).IsAssignableFrom(binding.type));
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta
new file mode 100644
index 0000000..6e5c8c3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/NotificationUtilities.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b90311a8f07b00f4bbeb2fff3b128d25
+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/Utilities/TimeUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs
new file mode 100644
index 0000000..549de4c
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Text.RegularExpressions;
+
+namespace UnityEngine.Timeline
+{
+ // Sequence specific utilities for time manipulation
+ static class TimeUtility
+ {
+ // chosen because it will cause no rounding errors between time/frames for frames values up to at least 10 million
+ public static readonly double kTimeEpsilon = 1e-14;
+ public static readonly double kFrameRateEpsilon = 1e-6;
+ public static readonly double k_MaxTimelineDurationInSeconds = 9e6; //104 days of running time
+
+ static void ValidateFrameRate(double frameRate)
+ {
+ if (frameRate <= kTimeEpsilon)
+ throw new ArgumentException("frame rate cannot be 0 or negative");
+ }
+
+ public static int ToFrames(double time, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ time = Math.Min(Math.Max(time, -k_MaxTimelineDurationInSeconds), k_MaxTimelineDurationInSeconds);
+ // this matches OnFrameBoundary
+ double tolerance = GetEpsilon(time, frameRate) / 2.0;
+ if (time < 0)
+ {
+ return (int)Math.Ceiling(time * frameRate - tolerance);
+ }
+ return (int)Math.Floor(time * frameRate + tolerance);
+ }
+
+ public static double ToExactFrames(double time, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ return time * frameRate;
+ }
+
+ public static double FromFrames(int frames, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ return (frames / frameRate);
+ }
+
+ public static double FromFrames(double frames, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+ return frames / frameRate;
+ }
+
+ public static bool OnFrameBoundary(double time, double frameRate)
+ {
+ return OnFrameBoundary(time, frameRate, GetEpsilon(time, frameRate));
+ }
+
+ public static double GetEpsilon(double time, double frameRate)
+ {
+ return Math.Max(Math.Abs(time), 1) * frameRate * kTimeEpsilon;
+ }
+
+ public static bool OnFrameBoundary(double time, double frameRate, double epsilon)
+ {
+ ValidateFrameRate(frameRate);
+
+ double exact = ToExactFrames(time, frameRate);
+ double rounded = Math.Round(exact);
+
+ return Math.Abs(exact - rounded) < epsilon;
+ }
+
+ public static double RoundToFrame(double time, double frameRate)
+ {
+ ValidateFrameRate(frameRate);
+
+ var frameBefore = (int)Math.Floor(time * frameRate) / frameRate;
+ var frameAfter = (int)Math.Ceiling(time * frameRate) / frameRate;
+
+ return Math.Abs(time - frameBefore) < Math.Abs(time - frameAfter) ? frameBefore : frameAfter;
+ }
+
+ public static string TimeAsFrames(double timeValue, double frameRate, string format = "F2")
+ {
+ if (OnFrameBoundary(timeValue, frameRate)) // make integral values when on time borders
+ return ToFrames(timeValue, frameRate).ToString();
+ return ToExactFrames(timeValue, frameRate).ToString(format);
+ }
+
+ public static string TimeAsTimeCode(double timeValue, double frameRate, string format = "F2")
+ {
+ ValidateFrameRate(frameRate);
+
+ int intTime = (int)Math.Abs(timeValue);
+
+ int hours = intTime / 3600;
+ int minutes = (intTime % 3600) / 60;
+ int seconds = intTime % 60;
+
+ string result;
+ string sign = timeValue < 0 ? "-" : string.Empty;
+ if (hours > 0)
+ result = hours + ":" + minutes.ToString("D2") + ":" + seconds.ToString("D2");
+ else if (minutes > 0)
+ result = minutes + ":" + seconds.ToString("D2");
+ else
+ result = seconds.ToString();
+
+ int frameDigits = (int)Math.Floor(Math.Log10(frameRate) + 1);
+
+ // Add partial digits on the frame if needed.
+ // we are testing the original value (not the truncated), because the truncation can cause rounding errors leading
+ // to invalid strings for items on frame boundaries
+ string frames = (ToFrames(timeValue, frameRate) - ToFrames(intTime, frameRate)).ToString().PadLeft(frameDigits, '0');
+ if (!OnFrameBoundary(timeValue, frameRate))
+ {
+ string decimals = ToExactFrames(timeValue, frameRate).ToString(format);
+ int decPlace = decimals.IndexOf('.');
+ if (decPlace >= 0)
+ frames += " [" + decimals.Substring(decPlace) + "]";
+ }
+
+ return sign + result + ":" + frames;
+ }
+
+ // Given a time code string, return the time in seconds
+ // 1.5 -> 1.5 seconds
+ // 1:1.5 -> 1 minute, 1.5 seconds
+ // 1:1[.5] -> 1 second, 1.5 frames
+ // 2:3:4 -> 2 minutes, 3 seconds, 4 frames
+ // 1[.6] -> 1.6 frames
+ public static double ParseTimeCode(string timeCode, double frameRate, double defaultValue)
+ {
+ timeCode = RemoveChar(timeCode, c => char.IsWhiteSpace(c));
+ string[] sections = timeCode.Split(':');
+ if (sections.Length == 0 || sections.Length > 4)
+ return defaultValue;
+
+ int hours = 0;
+ int minutes = 0;
+ double seconds = 0;
+ double frames = 0;
+
+ try
+ {
+ // depending on the format of the last numbers
+ // seconds format
+ string lastSection = sections[sections.Length - 1];
+ if (Regex.Match(lastSection, @"^\d+\.\d+$").Success)
+ {
+ seconds = double.Parse(lastSection);
+ if (sections.Length > 3) return defaultValue;
+ if (sections.Length > 1) minutes = int.Parse(sections[sections.Length - 2]);
+ if (sections.Length > 2) hours = int.Parse(sections[sections.Length - 3]);
+ }
+ // frame formats
+ else
+ {
+ if (Regex.Match(lastSection, @"^\d+\[\.\d+\]$").Success)
+ {
+ string stripped = RemoveChar(lastSection, c => c == '[' || c == ']');
+ frames = double.Parse(stripped);
+ }
+ else if (Regex.Match(lastSection, @"^\d*$").Success)
+ {
+ frames = int.Parse(lastSection);
+ }
+ else
+ {
+ return defaultValue;
+ }
+
+ if (sections.Length > 1) seconds = int.Parse(sections[sections.Length - 2]);
+ if (sections.Length > 2) minutes = int.Parse(sections[sections.Length - 3]);
+ if (sections.Length > 3) hours = int.Parse(sections[sections.Length - 4]);
+ }
+ }
+ catch (FormatException)
+ {
+ return defaultValue;
+ }
+
+ return frames / frameRate + seconds + minutes * 60 + hours * 3600;
+ }
+
+ // fixes rounding errors from using single precision for length
+ public static double GetAnimationClipLength(AnimationClip clip)
+ {
+ if (clip == null || clip.empty)
+ return 0;
+
+ double length = clip.length;
+ if (clip.frameRate > 0)
+ {
+ double frames = Mathf.Round(clip.length * clip.frameRate);
+ length = frames / clip.frameRate;
+ }
+ return length;
+ }
+
+ static string RemoveChar(string str, Func<char, bool> charToRemoveFunc)
+ {
+ var len = str.Length;
+ var src = str.ToCharArray();
+ var dstIdx = 0;
+ for (var i = 0; i < len; i++)
+ {
+ if (!charToRemoveFunc(src[i]))
+ src[dstIdx++] = src[i];
+ }
+ return new string(src, 0, dstIdx);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta
new file mode 100644
index 0000000..ff1d820
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimeUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f779e779d62b5ca49b658236c337845d
+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/Utilities/TimelineCreateUtilities.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs
new file mode 100644
index 0000000..0870e40
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace UnityEngine.Timeline
+{
+ static class TimelineCreateUtilities
+ {
+ // based off of ObjectNames.GetUniqueName, but can exist in runtime
+ public static string GenerateUniqueActorName(List<ScriptableObject> tracks, string name)
+ {
+ if (!tracks.Exists(x => ((object)x) != null && x.name == name))
+ return name;
+
+ int numberInParentheses = 0;
+ string baseName = name;
+
+ if (!string.IsNullOrEmpty(name) && name[name.Length - 1] == ')')
+ {
+ int index = name.LastIndexOf('(');
+ if (index > 0)
+ {
+ string numberString = name.Substring(index + 1, name.Length - index - 2);
+ if (int.TryParse(numberString, out numberInParentheses))
+ {
+ numberInParentheses++;
+ baseName = name.Substring(0, index);
+ }
+ }
+ }
+
+ baseName = baseName.TrimEnd();
+
+ for (int i = numberInParentheses; i < numberInParentheses + 5000; i++)
+ {
+ if (i > 0)
+ {
+ string result = string.Format("{0} ({1})", baseName, i);
+ if (!tracks.Exists(x => ((object)x) != null && x.name == result))
+ return result;
+ }
+ }
+
+ // Fallback
+ return name;
+ }
+
+ public static void SaveAssetIntoObject(Object childAsset, Object masterAsset)
+ {
+ if (childAsset == null || masterAsset == null)
+ return;
+
+ if ((masterAsset.hideFlags & HideFlags.DontSave) != 0)
+ {
+ childAsset.hideFlags |= HideFlags.DontSave;
+ }
+ else
+ {
+ childAsset.hideFlags |= HideFlags.HideInHierarchy;
+#if UNITY_EDITOR
+ if (!AssetDatabase.Contains(childAsset) && AssetDatabase.Contains(masterAsset))
+ AssetDatabase.AddObjectToAsset(childAsset, masterAsset);
+#endif
+ }
+ }
+
+ public static AnimationClip CreateAnimationClipForTrack(string name, TrackAsset track, bool isLegacy)
+ {
+ var timelineAsset = track != null ? track.timelineAsset : null;
+ var trackFlags = track != null ? track.hideFlags : HideFlags.None;
+
+ var curves = new AnimationClip
+ {
+ legacy = isLegacy,
+
+ name = name,
+
+ frameRate = timelineAsset == null
+ ? TimelineAsset.EditorSettings.kDefaultFps
+ : timelineAsset.editorSettings.fps
+ };
+
+ SaveAssetIntoObject(curves, timelineAsset);
+ curves.hideFlags = trackFlags & ~HideFlags.HideInHierarchy; // Never hide in hierarchy
+
+ TimelineUndo.RegisterCreatedObjectUndo(curves, "Create Curves");
+
+ return curves;
+ }
+
+ public static bool ValidateParentTrack(TrackAsset parent, Type childType)
+ {
+ if (childType == null || !typeof(TrackAsset).IsAssignableFrom(childType))
+ return false;
+
+ // no parent is valid for any type
+ if (parent == null)
+ return true;
+
+ // A track supports layers if it implements ILayerable. Only supported for parents that are
+ // the same exact type as the child class, and 1 level of nesting only
+ if (parent is ILayerable && !parent.isSubTrack && parent.GetType() == childType)
+ return true;
+
+ var attr = Attribute.GetCustomAttribute(parent.GetType(), typeof(SupportsChildTracksAttribute)) as SupportsChildTracksAttribute;
+ if (attr == null)
+ return false;
+
+ // group track case, accepts all
+ if (attr.childType == null)
+ return true;
+
+ // specific case. Specifies nesting level
+ if (childType == attr.childType)
+ {
+ int nestCount = 0;
+ var p = parent;
+ while (p != null && p.isSubTrack)
+ {
+ nestCount++;
+ p = p.parent as TrackAsset;
+ }
+
+ return nestCount < attr.levels;
+ }
+ return false;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta
new file mode 100644
index 0000000..f81aa91
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineCreateUtilities.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 40cb137d0e9816e48a4141ed13afedad
+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/Utilities/TimelineUndo.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs
new file mode 100644
index 0000000..b6392f0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using UnityEngine.Playables;
+
+#if UNITY_EDITOR
+using UnityEditor;
+#endif
+
+namespace UnityEngine.Timeline
+{
+ static class TimelineUndo
+ {
+ public static void PushDestroyUndo(TimelineAsset timeline, Object thingToDirty, Object objectToDestroy, string operation)
+ {
+#if UNITY_EDITOR
+ if (objectToDestroy == null || !DisableUndoGuard.enableUndo)
+ return;
+
+ if (thingToDirty != null)
+ EditorUtility.SetDirty(thingToDirty);
+
+ if (timeline != null)
+ EditorUtility.SetDirty(timeline);
+
+ Undo.DestroyObjectImmediate(objectToDestroy);
+#else
+ if (objectToDestroy != null)
+ Object.Destroy(objectToDestroy);
+#endif
+ }
+
+ [Conditional("UNITY_EDITOR")]
+ public static void PushUndo(Object thingToDirty, string operation)
+ {
+#if UNITY_EDITOR
+ if (thingToDirty != null && DisableUndoGuard.enableUndo)
+ {
+ var track = thingToDirty as TrackAsset;
+ if (track != null)
+ track.MarkDirty();
+
+ EditorUtility.SetDirty(thingToDirty);
+ Undo.RegisterCompleteObjectUndo(thingToDirty, "Timeline " + operation);
+ }
+#endif
+ }
+
+ [Conditional("UNITY_EDITOR")]
+ public static void RegisterCreatedObjectUndo(Object thingCreated, string operation)
+ {
+#if UNITY_EDITOR
+ if (DisableUndoGuard.enableUndo)
+ {
+ Undo.RegisterCreatedObjectUndo(thingCreated, "Timeline " + operation);
+ }
+#endif
+ }
+
+#if UNITY_EDITOR
+ public struct DisableUndoGuard : IDisposable
+ {
+ internal static bool enableUndo = true;
+ static readonly Stack<bool> m_UndoStateStack = new Stack<bool>();
+ bool m_Disposed;
+ public DisableUndoGuard(bool disable)
+ {
+ m_Disposed = false;
+ m_UndoStateStack.Push(enableUndo);
+ enableUndo = !disable;
+ }
+
+ public void Dispose()
+ {
+ if (!m_Disposed)
+ {
+ if (m_UndoStateStack.Count == 0)
+ {
+ Debug.LogError("UnMatched DisableUndoGuard calls");
+ enableUndo = true;
+ return;
+ }
+ enableUndo = m_UndoStateStack.Pop();
+ m_Disposed = true;
+ }
+ }
+ }
+#endif
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta
new file mode 100644
index 0000000..c62c751
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/TimelineUndo.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1f2a7e0d1b6bbba408a41e206945c23c
+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/Utilities/WeightUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs
new file mode 100644
index 0000000..22db909
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs
@@ -0,0 +1,30 @@
+using UnityEngine.Playables;
+
+namespace UnityEngine.Timeline
+{
+ static class WeightUtility
+ {
+ // Given a mixer, normalizes the mixer if required
+ // returns the output weight that should be applied to the mixer as input
+ public static float NormalizeMixer(Playable mixer)
+ {
+ if (!mixer.IsValid())
+ return 0;
+ int count = mixer.GetInputCount();
+ float weight = 0.0f;
+ for (int c = 0; c < count; c++)
+ {
+ weight += mixer.GetInputWeight(c);
+ }
+
+ if (weight > Mathf.Epsilon && weight < 1)
+ {
+ for (int c = 0; c < count; c++)
+ {
+ mixer.SetInputWeight(c, mixer.GetInputWeight(c) / weight);
+ }
+ }
+ return Mathf.Clamp01(weight);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta
new file mode 100644
index 0000000..bf2c55d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Utilities/WeightUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e7a505b341283e14696e86433a5b1ae9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: