summaryrefslogtreecommitdiff
path: root/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities
diff options
context:
space:
mode:
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities')
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs91
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs358
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs58
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs235
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs386
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs142
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs62
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs47
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs33
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs21
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs18
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs20
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs34
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs109
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs203
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs66
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs28
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs195
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs226
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs49
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs32
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs127
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs60
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs23
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs57
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs387
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs21
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs121
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs.meta11
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs342
-rw-r--r--Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs.meta11
58 files changed, 3870 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs
new file mode 100644
index 0000000..d5f091f
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace UnityEditor.Timeline
+{
+ static class AnimatedParameterCache
+ {
+ static readonly Dictionary<Type, FieldInfo[]> k_ScriptPlayableFieldsCache = new Dictionary<Type, FieldInfo[]>();
+ static readonly Dictionary<PropertyKey, FieldInfo> k_PropertyFieldInfoCache = new Dictionary<PropertyKey, FieldInfo>();
+ static readonly Dictionary<PropertyKey, bool> k_PropertyIsAnimatableCache = new Dictionary<PropertyKey, bool>();
+ static readonly Dictionary<PropertyKey, string> k_BindingNameCache = new Dictionary<PropertyKey, string>();
+
+ public static bool TryGetScriptPlayableFields(Type type, out FieldInfo[] scriptPlayableFields)
+ {
+ return k_ScriptPlayableFieldsCache.TryGetValue(type, out scriptPlayableFields);
+ }
+
+ public static void SetScriptPlayableFields(Type type, FieldInfo[] scriptPlayableFields)
+ {
+ k_ScriptPlayableFieldsCache[type] = scriptPlayableFields;
+ }
+
+ public static bool TryGetFieldInfoForProperty(SerializedProperty property, out FieldInfo fieldInfo)
+ {
+ return k_PropertyFieldInfoCache.TryGetValue(new PropertyKey(property), out fieldInfo);
+ }
+
+ public static void SetFieldInfoForProperty(SerializedProperty property, FieldInfo fieldInfo)
+ {
+ k_PropertyFieldInfoCache[new PropertyKey(property)] = fieldInfo;
+ }
+
+ public static bool TryGetIsPropertyAnimatable(SerializedProperty property, out bool isAnimatable)
+ {
+ return k_PropertyIsAnimatableCache.TryGetValue(new PropertyKey(property), out isAnimatable);
+ }
+
+ public static void SetIsPropertyAnimatable(SerializedProperty property, bool isAnimatable)
+ {
+ k_PropertyIsAnimatableCache[new PropertyKey(property)] = isAnimatable;
+ }
+
+ public static bool TryGetBindingName(Type type, string path, out string bindingName)
+ {
+ return k_BindingNameCache.TryGetValue(new PropertyKey(type, path), out bindingName);
+ }
+
+ public static void SetBindingName(Type type, string path, string bindingName)
+ {
+ k_BindingNameCache[new PropertyKey(type, path)] = bindingName;
+ }
+ }
+
+ struct PropertyKey : IEquatable<PropertyKey>
+ {
+ readonly Type m_Type;
+ readonly string m_Path;
+
+ public PropertyKey(SerializedProperty property)
+ {
+ m_Type = property.serializedObject.targetObject.GetType();
+ m_Path = property.propertyPath;
+ }
+
+ public PropertyKey(Type type, string path)
+ {
+ m_Type = type;
+ m_Path = path;
+ }
+
+ public bool Equals(PropertyKey other)
+ {
+ return m_Type == other.m_Type && string.Equals(m_Path, other.m_Path);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj)) return false;
+ return obj is PropertyKey && Equals((PropertyKey)obj);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ return ((m_Type != null ? m_Type.GetHashCode() : 0) * 397) ^ (m_Path != null ? m_Path.GetHashCode() : 0);
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs.meta
new file mode 100644
index 0000000..19831f1
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterCache.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1fe0f539450e54dbc85bfb2fa6b466fb
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs
new file mode 100644
index 0000000..53542e3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs
@@ -0,0 +1,358 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using UnityObject = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ static class AnimatedParameterUtility
+ {
+ static readonly Type k_DefaultAnimationType = typeof(TimelineAsset);
+ static SerializedObject s_CachedObject;
+
+ public static ICurvesOwner ToCurvesOwner(IPlayableAsset playableAsset, TimelineAsset timeline)
+ {
+ if (playableAsset == null)
+ return null;
+
+ var curvesOwner = playableAsset as ICurvesOwner;
+ if (curvesOwner == null)
+ {
+ // If the asset is not directly an ICurvesOwner, it might be the asset for a TimelineClip
+ curvesOwner = TimelineRecording.FindClipWithAsset(timeline, playableAsset);
+ }
+
+ return curvesOwner;
+ }
+
+ public static bool TryGetSerializedPlayableAsset(UnityObject asset, out SerializedObject serializedObject)
+ {
+ serializedObject = null;
+ if (asset == null || Attribute.IsDefined(asset.GetType(), typeof(NotKeyableAttribute)) || !HasScriptPlayable(asset))
+ return false;
+
+ serializedObject = GetSerializedPlayableAsset(asset);
+ return serializedObject != null;
+ }
+
+ public static SerializedObject GetSerializedPlayableAsset(UnityObject asset)
+ {
+ if (!(asset is IPlayableAsset))
+ return null;
+
+ var scriptObject = asset as ScriptableObject;
+ if (scriptObject == null)
+ return null;
+
+ if (s_CachedObject == null || s_CachedObject.targetObject != asset)
+ {
+ s_CachedObject = new SerializedObject(scriptObject);
+ }
+
+ return s_CachedObject;
+ }
+
+ public static void UpdateSerializedPlayableAsset(UnityObject asset)
+ {
+ var so = GetSerializedPlayableAsset(asset);
+ if (so != null)
+ so.UpdateIfRequiredOrScript();
+ }
+
+ public static bool HasScriptPlayable(UnityObject asset)
+ {
+ if (asset == null)
+ return false;
+
+ var scriptPlayable = asset as IPlayableBehaviour;
+ return scriptPlayable != null || GetScriptPlayableFields(asset as IPlayableAsset).Any();
+ }
+
+ public static FieldInfo[] GetScriptPlayableFields(IPlayableAsset asset)
+ {
+ if (asset == null)
+ return new FieldInfo[0];
+
+ FieldInfo[] scriptPlayableFields;
+ if (!AnimatedParameterCache.TryGetScriptPlayableFields(asset.GetType(), out scriptPlayableFields))
+ {
+ scriptPlayableFields = GetScriptPlayableFields_Internal(asset);
+ AnimatedParameterCache.SetScriptPlayableFields(asset.GetType(), scriptPlayableFields);
+ }
+
+ return scriptPlayableFields;
+ }
+
+ static FieldInfo[] GetScriptPlayableFields_Internal(IPlayableAsset asset)
+ {
+ return asset.GetType()
+ .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
+ .Where(
+ f => typeof(IPlayableBehaviour).IsAssignableFrom(f.FieldType) && // The field is an IPlayableBehaviour
+ (f.IsPublic || f.GetCustomAttributes(typeof(SerializeField), false).Any()) && // The field is either public or marked with [SerializeField]
+ !f.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any() && // The field is not marked with [NotKeyable]
+ !f.GetCustomAttributes(typeof(HideInInspector), false).Any() && // The field is not marked with [HideInInspector]
+ !f.FieldType.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any()) // The field is not of a type marked with [NotKeyable]
+ .ToArray();
+ }
+
+ public static bool HasAnyAnimatableParameters(UnityObject asset)
+ {
+ return GetAllAnimatableParameters(asset).Any();
+ }
+
+ public static IEnumerable<SerializedProperty> GetAllAnimatableParameters(UnityObject asset)
+ {
+ SerializedObject serializedObject;
+ if (!TryGetSerializedPlayableAsset(asset, out serializedObject))
+ yield break;
+
+ var prop = serializedObject.GetIterator();
+
+ // We need to keep this variable because prop starts invalid
+ var outOfBounds = false;
+ while (!outOfBounds && prop.NextVisible(true))
+ {
+ foreach (var property in SelectAnimatableProperty(prop))
+ yield return property;
+
+ // We can become out of bounds by calling SelectAnimatableProperty, if the last iterated property is a color.
+ outOfBounds = !prop.isValid;
+ }
+ }
+
+ static IEnumerable<SerializedProperty> SelectAnimatableProperty(SerializedProperty prop)
+ {
+ // We're only interested by animatable leaf parameters
+ if (!prop.hasChildren && IsParameterAnimatable(prop))
+ yield return prop.Copy();
+
+ // Color type is not considered "visible" when iterating
+ if (prop.propertyType == SerializedPropertyType.Color)
+ {
+ var end = prop.GetEndProperty();
+
+ // For some reasons, if the last 2+ serialized properties are of type Color, prop becomes invalid and
+ // Next() throws an exception. This is not the case when only the last serialized property is a Color.
+ while (!SerializedProperty.EqualContents(prop, end) && prop.isValid && prop.Next(true))
+ {
+ foreach (var property in SelectAnimatableProperty(prop))
+ yield return property;
+ }
+ }
+ }
+
+ public static bool IsParameterAnimatable(UnityObject asset, string parameterName)
+ {
+ SerializedObject serializedObject;
+ if (!TryGetSerializedPlayableAsset(asset, out serializedObject))
+ return false;
+
+ var prop = serializedObject.FindProperty(parameterName);
+ return IsParameterAnimatable(prop);
+ }
+
+ public static bool IsParameterAnimatable(SerializedProperty property)
+ {
+ if (property == null)
+ return false;
+
+ bool isAnimatable;
+ if (!AnimatedParameterCache.TryGetIsPropertyAnimatable(property, out isAnimatable))
+ {
+ isAnimatable = IsParameterAnimatable_Internal(property);
+ AnimatedParameterCache.SetIsPropertyAnimatable(property, isAnimatable);
+ }
+
+ return isAnimatable;
+ }
+
+ static bool IsParameterAnimatable_Internal(SerializedProperty property)
+ {
+ if (property == null)
+ return false;
+
+ var asset = property.serializedObject.targetObject;
+
+ // Currently not supported
+ if (asset is AnimationTrack)
+ return false;
+
+ if (IsParameterKeyable(property))
+ return asset is IPlayableBehaviour || IsParameterAtPathAnimatable(asset, property.propertyPath);
+
+ return false;
+ }
+
+ static bool IsParameterKeyable(SerializedProperty property)
+ {
+ return IsTypeAnimatable(property.propertyType) && IsKeyableInHierarchy(property);
+ }
+
+ static bool IsKeyableInHierarchy(SerializedProperty property)
+ {
+ const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+ var pathSegments = property.propertyPath.Split('.');
+ var type = property.serializedObject.targetObject.GetType();
+ foreach (var segment in pathSegments)
+ {
+ if (type.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any())
+ {
+ return false;
+ }
+
+ if (type.IsArray)
+ {
+ if (segment != "Array")
+ type = type.GetElementType();
+ continue;
+ }
+
+ var fieldInfo = type.GetField(segment, bindingFlags);
+
+ if (fieldInfo == null ||
+ fieldInfo.GetCustomAttributes(typeof(NotKeyableAttribute), false).Any() ||
+ fieldInfo.GetCustomAttributes(typeof(HideInInspector), false).Any())
+ {
+ return false;
+ }
+
+ type = fieldInfo.FieldType;
+ }
+
+ return true;
+ }
+
+ static bool IsParameterAtPathAnimatable(UnityObject asset, string path)
+ {
+ if (asset == null)
+ return false;
+
+ return GetScriptPlayableFields(asset as IPlayableAsset)
+ .Any(
+ f => path.StartsWith(f.Name, StringComparison.Ordinal) &&
+ path.Length > f.Name.Length &&
+ path[f.Name.Length] == '.');
+ }
+
+ public static bool IsTypeAnimatable(SerializedPropertyType type)
+ {
+ // Note: Integer is not currently supported by the animated property system
+ switch (type)
+ {
+ case SerializedPropertyType.Boolean:
+ case SerializedPropertyType.Float:
+ case SerializedPropertyType.Vector2:
+ case SerializedPropertyType.Vector3:
+ case SerializedPropertyType.Color:
+ case SerializedPropertyType.Quaternion:
+ case SerializedPropertyType.Vector4:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public static bool IsParameterAnimated(UnityObject asset, AnimationClip animationData, string parameterName)
+ {
+ if (asset == null || animationData == null)
+ return false;
+
+ var binding = GetCurveBinding(asset, parameterName);
+ var bindings = AnimationClipCurveCache.Instance.GetCurveInfo(animationData).bindings;
+ return bindings.Any(x => BindingMatchesParameterName(x, binding.propertyName));
+ }
+
+ // Retrieve an animated parameter curve. parameter name is required to include the appropriate field for vectors
+ // e.g.: position
+ public static AnimationCurve GetAnimatedParameter(UnityObject asset, AnimationClip animationData, string parameterName)
+ {
+ if (!(asset is ScriptableObject) || animationData == null)
+ return null;
+
+ var binding = GetCurveBinding(asset, parameterName);
+ return AnimationUtility.GetEditorCurve(animationData, binding);
+ }
+
+ // get an animatable curve binding for this parameter
+ public static EditorCurveBinding GetCurveBinding(UnityObject asset, string parameterName)
+ {
+ var animationName = GetAnimatedParameterBindingName(asset, parameterName);
+ return EditorCurveBinding.FloatCurve(string.Empty, GetValidAnimationType(asset), animationName);
+ }
+
+ public static string GetAnimatedParameterBindingName(UnityObject asset, string parameterName)
+ {
+ if (asset == null)
+ return parameterName;
+
+ string bindingName;
+ if (!AnimatedParameterCache.TryGetBindingName(asset.GetType(), parameterName, out bindingName))
+ {
+ bindingName = GetAnimatedParameterBindingName_Internal(asset, parameterName);
+ AnimatedParameterCache.SetBindingName(asset.GetType(), parameterName, bindingName);
+ }
+
+ return bindingName;
+ }
+
+ static string GetAnimatedParameterBindingName_Internal(UnityObject asset, string parameterName)
+ {
+ if (asset is IPlayableBehaviour)
+ return parameterName;
+
+ // strip the IScript playable field name
+ var fields = GetScriptPlayableFields(asset as IPlayableAsset);
+ foreach (var f in fields)
+ {
+ if (parameterName.StartsWith(f.Name, StringComparison.Ordinal))
+ {
+ if (parameterName.Length > f.Name.Length && parameterName[f.Name.Length] == '.')
+ return parameterName.Substring(f.Name.Length + 1);
+ }
+ }
+
+ return parameterName;
+ }
+
+ public static bool BindingMatchesParameterName(EditorCurveBinding binding, string parameterName)
+ {
+ if (binding.propertyName == parameterName)
+ return true;
+
+ var indexOfDot = binding.propertyName.IndexOf('.');
+ return indexOfDot > 0 && parameterName.Length == indexOfDot &&
+ binding.propertyName.StartsWith(parameterName, StringComparison.Ordinal);
+ }
+
+ // the animated type must be a non-abstract instantiable object.
+ public static Type GetValidAnimationType(UnityObject asset)
+ {
+ return asset != null ? asset.GetType() : k_DefaultAnimationType;
+ }
+
+ public static FieldInfo GetFieldInfoForProperty(SerializedProperty property)
+ {
+ FieldInfo fieldInfo;
+
+ if (!AnimatedParameterCache.TryGetFieldInfoForProperty(property, out fieldInfo))
+ {
+ Type _;
+ fieldInfo = ScriptAttributeUtility.GetFieldInfoFromProperty(property, out _);
+ AnimatedParameterCache.SetFieldInfoForProperty(property, fieldInfo);
+ }
+
+ return fieldInfo;
+ }
+
+ public static T GetAttributeForProperty<T>(SerializedProperty property) where T : Attribute
+ {
+ var fieldInfo = GetFieldInfoForProperty(property);
+ return fieldInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault() as T;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs.meta
new file mode 100644
index 0000000..695849f
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/AnimatedParameterUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 84d86c98104d94063ad70bc591530f65
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs
new file mode 100644
index 0000000..5565817
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs
@@ -0,0 +1,58 @@
+using System;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using Object = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ static class BindingUtility
+ {
+ public static Type GetRequiredBindingType(PlayableBinding binding)
+ {
+ return binding.outputTargetType;
+ }
+
+ public static void Bind(PlayableDirector director, TrackAsset bindTo, Object objectToBind)
+ {
+ if (director == null || bindTo == null || TimelineWindow.instance == null)
+ return;
+
+ TimelineWindow.instance.state.previewMode = false; // returns all objects to previous state
+ TimelineUndo.PushUndo(director, "PlayableDirector Binding");
+ director.SetGenericBinding(bindTo, objectToBind);
+ TimelineWindow.instance.state.rebuildGraph = true;
+ }
+
+ public static BindingAction GetBindingAction(Type requiredBindingType, Object objectToBind)
+ {
+ if (requiredBindingType == null || objectToBind == null)
+ return BindingAction.DoNotBind;
+
+ // prevent drag and drop of prefab assets
+ if (PrefabUtility.IsPartOfPrefabAsset(objectToBind))
+ return BindingAction.DoNotBind;
+
+ if (requiredBindingType.IsInstanceOfType(objectToBind))
+ return BindingAction.BindDirectly;
+
+ var draggedGameObject = objectToBind as GameObject;
+
+ if (!typeof(Component).IsAssignableFrom(requiredBindingType) || draggedGameObject == null)
+ return BindingAction.DoNotBind;
+
+ if (draggedGameObject.GetComponent(requiredBindingType) == null)
+ return BindingAction.BindToMissingComponent;
+
+ return BindingAction.BindToExistingComponent;
+ }
+ }
+
+ enum BindingAction
+ {
+ DoNotBind,
+ BindDirectly,
+ BindToExistingComponent,
+ BindToMissingComponent
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs.meta
new file mode 100644
index 0000000..c528748
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BindingUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ef5fa6e2005defb4ab5142723827b58e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs
new file mode 100644
index 0000000..a3276bf
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs
@@ -0,0 +1,235 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ enum TitleMode
+ {
+ None,
+ DisabledComponent,
+ Prefab,
+ PrefabOutOfContext,
+ Asset,
+ GameObject
+ }
+
+ struct BreadCrumbTitle
+ {
+ public string name;
+ public TitleMode mode;
+ }
+
+ class BreadcrumbDrawer
+ {
+ static readonly GUIContent s_TextContent = new GUIContent();
+ static readonly string k_DisabledComponentText = L10n.Tr("The PlayableDirector is disabled");
+ static readonly string k_PrefabOutOfContext = L10n.Tr("Prefab Isolation not enabled. Click to Enable.");
+
+ static readonly GUIStyle k_BreadCrumbLeft;
+ static readonly GUIStyle k_BreadCrumbMid;
+ static readonly GUIStyle k_BreadCrumbLeftBg;
+ static readonly GUIStyle k_BreadCrumbMidBg;
+ static readonly GUIStyle k_BreadCrumbMidSelected;
+ static readonly GUIStyle k_BreadCrumbMidBgSelected;
+
+ static readonly Texture k_TimelineIcon;
+
+ const string k_Elipsis = "…";
+
+ static BreadcrumbDrawer()
+ {
+ k_BreadCrumbLeft = new GUIStyle("GUIEditor.BreadcrumbLeft");
+ k_BreadCrumbMid = new GUIStyle("GUIEditor.BreadcrumbMid");
+ k_BreadCrumbLeftBg = new GUIStyle("GUIEditor.BreadcrumbLeftBackground");
+ k_BreadCrumbMidBg = new GUIStyle("GUIEditor.BreadcrumbMidBackground");
+
+ k_BreadCrumbMidSelected = new GUIStyle(k_BreadCrumbMid);
+ k_BreadCrumbMidSelected.normal = k_BreadCrumbMidSelected.onNormal;
+
+ k_BreadCrumbMidBgSelected = new GUIStyle(k_BreadCrumbMidBg);
+ k_BreadCrumbMidBgSelected.normal = k_BreadCrumbMidBgSelected.onNormal;
+ k_TimelineIcon = EditorGUIUtility.IconContent("TimelineAsset Icon").image;
+ }
+
+ static string FitTextInArea(float areaWidth, string text, GUIStyle style)
+ {
+ var borderWidth = style.border.left + style.border.right;
+ var textWidth = style.CalcSize(EditorGUIUtility.TextContent(text)).x;
+
+ if (borderWidth + textWidth < areaWidth)
+ return text;
+
+ // Need to truncate the text to fit in the areaWidth
+ var textAreaWidth = areaWidth - borderWidth;
+ var pixByChar = textWidth / text.Length;
+ var charNeeded = (int)Mathf.Floor(textAreaWidth / pixByChar);
+ charNeeded -= k_Elipsis.Length;
+
+ if (charNeeded <= 0)
+ return k_Elipsis;
+
+ if (charNeeded <= text.Length)
+ return k_Elipsis + " " + text.Substring(text.Length - charNeeded);
+
+ return k_Elipsis;
+ }
+
+ public static void Draw(float breadcrumbAreaWidth, List<BreadCrumbTitle> labels, Action<int> navigateToBreadcrumbIndex)
+ {
+ GUILayout.BeginHorizontal(GUILayout.Width(breadcrumbAreaWidth));
+ {
+ var labelWidth = (int)(breadcrumbAreaWidth / labels.Count);
+
+ for (var i = 0; i < labels.Count; i++)
+ {
+ var label = labels[i];
+
+ var style = i == 0 ? k_BreadCrumbLeft : k_BreadCrumbMid;
+ var backgroundStyle = i == 0 ? k_BreadCrumbLeftBg : k_BreadCrumbMidBg;
+
+ if (i == labels.Count - 1)
+ {
+ if (i > 0)
+ {
+ // Only tint last breadcrumb if we are dug-in
+ DrawBreadcrumbAsSelectedSubSequence(labelWidth, label, k_BreadCrumbMidSelected, k_BreadCrumbMidBgSelected);
+ }
+ else
+ {
+ DrawActiveBreadcrumb(labelWidth, label, style, backgroundStyle);
+ }
+ }
+ else
+ {
+ var previousContentColor = GUI.contentColor;
+
+ GUI.contentColor = new Color(previousContentColor.r,
+ previousContentColor.g,
+ previousContentColor.b,
+ previousContentColor.a * 0.6f);
+ var content = GetTextContent(labelWidth, label, style);
+ var rect = GetBreadcrumbLayoutRect(content, style);
+
+ if (Event.current.type == EventType.Repaint)
+ {
+ backgroundStyle.Draw(rect, GUIContent.none, 0);
+ }
+
+ if (GUI.Button(rect, content, style))
+ {
+ navigateToBreadcrumbIndex.Invoke(i);
+ }
+ GUI.contentColor = previousContentColor;
+ }
+ }
+ }
+ GUILayout.EndHorizontal();
+ }
+
+ static GUIContent GetTextContent(int width, BreadCrumbTitle text, GUIStyle style)
+ {
+ s_TextContent.tooltip = string.Empty;
+ s_TextContent.image = null;
+ if (text.mode == TitleMode.DisabledComponent)
+ {
+ s_TextContent.tooltip = k_DisabledComponentText;
+ s_TextContent.image = EditorGUIUtility.GetHelpIcon(MessageType.Warning);
+ }
+ else if (text.mode == TitleMode.Prefab)
+ s_TextContent.image = PrefabUtility.GameObjectStyles.prefabIcon;
+ else if (text.mode == TitleMode.GameObject)
+ s_TextContent.image = PrefabUtility.GameObjectStyles.gameObjectIcon;
+ else if (text.mode == TitleMode.Asset)
+ s_TextContent.image = k_TimelineIcon;
+ else if (text.mode == TitleMode.PrefabOutOfContext)
+ {
+ s_TextContent.image = PrefabUtility.GameObjectStyles.prefabIcon;
+ if (!TimelineWindow.instance.locked)
+ s_TextContent.tooltip = k_PrefabOutOfContext;
+ }
+
+ if (s_TextContent.image != null)
+ width = Math.Max(0, width - s_TextContent.image.width);
+ s_TextContent.text = FitTextInArea(width, text.name, style);
+
+ return s_TextContent;
+ }
+
+ static void DrawBreadcrumbAsSelectedSubSequence(int width, BreadCrumbTitle label, GUIStyle style, GUIStyle backgroundStyle)
+ {
+ var rect = DrawActiveBreadcrumb(width, label, style, backgroundStyle);
+ const float underlineThickness = 2.0f;
+ const float underlineVerticalOffset = 0.0f;
+ var underlineHorizontalOffset = backgroundStyle.border.right * 0.333f;
+ var underlineRect = Rect.MinMaxRect(
+ rect.xMin - underlineHorizontalOffset,
+ rect.yMax - underlineThickness - underlineVerticalOffset,
+ rect.xMax - underlineHorizontalOffset,
+ rect.yMax - underlineVerticalOffset);
+
+ EditorGUI.DrawRect(underlineRect, DirectorStyles.Instance.customSkin.colorSubSequenceDurationLine);
+ }
+
+ static Rect GetBreadcrumbLayoutRect(GUIContent content, GUIStyle style)
+ {
+ // the image makes the button far too big compared to non-image versions
+ var image = content.image;
+ content.image = null;
+ var size = style.CalcSizeWithConstraints(content, Vector2.zero);
+ content.image = image;
+ if (image != null)
+ size.x += size.y; // assumes square image, constrained by height
+
+ return GUILayoutUtility.GetRect(content, style, GUILayout.MaxWidth(size.x));
+ }
+
+ static Rect DrawActiveBreadcrumb(int width, BreadCrumbTitle label, GUIStyle style, GUIStyle backgroundStyle)
+ {
+ var content = GetTextContent(width, label, style);
+ var rect = GetBreadcrumbLayoutRect(content, style);
+
+ if (Event.current.type == EventType.Repaint)
+ {
+ backgroundStyle.Draw(rect, GUIContent.none, 0);
+ }
+
+ if (GUI.Button(rect, content, style))
+ {
+ UnityEngine.Object target = TimelineEditor.inspectedDirector;
+ if (target == null)
+ target = TimelineEditor.inspectedAsset;
+ if (target != null)
+ {
+ bool ping = true;
+ if (label.mode == TitleMode.PrefabOutOfContext)
+ {
+ var gameObject = PrefabUtility.GetRootGameObject(target);
+ if (gameObject != null)
+ {
+ target = gameObject; // ping the prefab root if it's locked.
+ if (!TimelineWindow.instance.locked)
+ {
+ var assetPath = AssetDatabase.GetAssetPath(gameObject);
+ if (!string.IsNullOrEmpty(assetPath))
+ {
+ var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.OpenPrefab(assetPath);
+ if (stage != null)
+ ping = false;
+ }
+ }
+ }
+ }
+
+ if (ping)
+ {
+ EditorGUIUtility.PingObject(target);
+ }
+ }
+ }
+
+ return rect;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs.meta
new file mode 100644
index 0000000..b17803a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 526f285e8d4fb8140b4cdfeb9102d8cb
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs
new file mode 100644
index 0000000..8c54f4d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs
@@ -0,0 +1,386 @@
+using System;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+using UnityEngine.Playables;
+
+namespace UnityEditor.Timeline
+{
+ static class ClipModifier
+ {
+ public static bool Delete(TimelineAsset timeline, TimelineClip clip)
+ {
+ return timeline.DeleteClip(clip);
+ }
+
+ public static bool Tile(TimelineClip[] clips)
+ {
+ if (clips.Length < 2)
+ return false;
+
+ var clipsByTracks = clips.GroupBy(x => x.parentTrack)
+ .Select(track => new {track.Key, Items = track.OrderBy(c => c.start)});
+
+ foreach (var track in clipsByTracks)
+ {
+ TimelineUndo.PushUndo(track.Key, "Tile");
+ }
+
+ foreach (var track in clipsByTracks)
+ {
+ double newStart = track.Items.First().start;
+ foreach (var c in track.Items)
+ {
+ c.start = newStart;
+ newStart += c.duration;
+ }
+ }
+
+ return true;
+ }
+
+ public static bool TrimStart(TimelineClip[] clips, double trimTime)
+ {
+ var result = false;
+
+ foreach (var clip in clips)
+ result |= TrimStart(clip, trimTime);
+
+ return result;
+ }
+
+ public static bool TrimStart(TimelineClip clip, double trimTime)
+ {
+ if (clip.asset == null)
+ return false;
+
+ if (clip.start > trimTime)
+ return false;
+
+ if (clip.end < trimTime)
+ return false;
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Trim Clip Start");
+
+ // Note: We are NOT using edit modes in this case because we want the same result
+ // regardless of the selected EditMode: split at cursor and delete left part
+ SetStart(clip, trimTime);
+
+ return true;
+ }
+
+ public static bool TrimEnd(TimelineClip[] clips, double trimTime)
+ {
+ var result = false;
+
+ foreach (var clip in clips)
+ result |= TrimEnd(clip, trimTime);
+
+ return result;
+ }
+
+ public static bool TrimEnd(TimelineClip clip, double trimTime)
+ {
+ if (clip.asset == null)
+ return false;
+
+ if (clip.start > trimTime)
+ return false;
+
+ if (clip.end < trimTime)
+ return false;
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Trim Clip End");
+ TrimClipWithEditMode(clip, TrimEdge.End, trimTime);
+
+ return true;
+ }
+
+ public static bool MatchDuration(TimelineClip[] clips)
+ {
+ double referenceDuration = clips[0].duration;
+ foreach (var clip in clips)
+ {
+ TimelineUndo.PushUndo(clip.parentTrack, "Match Clip Duration");
+
+ var newEnd = clip.start + referenceDuration;
+ TrimClipWithEditMode(clip, TrimEdge.End, newEnd);
+ }
+
+ return true;
+ }
+
+ public static bool Split(TimelineClip[] clips, double splitTime, PlayableDirector director)
+ {
+ var result = false;
+
+ foreach (var clip in clips)
+ {
+ if (clip.start >= splitTime)
+ continue;
+
+ if (clip.end <= splitTime)
+ continue;
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Split Clip");
+
+ TimelineClip newClip = TimelineHelpers.Clone(clip, director, director, clip.start);
+
+ SetStart(clip, splitTime);
+ SetEnd(newClip, splitTime, false);
+
+ // Sort produced by cloning clips on top of each other is unpredictable (it varies between mono runtimes)
+ clip.parentTrack.SortClips();
+
+ result = true;
+ }
+
+ return result;
+ }
+
+ public static void SetStart(TimelineClip clip, double time)
+ {
+ var supportsClipIn = clip.SupportsClipIn();
+ var supportsPadding = TimelineUtility.IsRecordableAnimationClip(clip);
+
+ // treat empty recordable clips as not supporting clip in (there are no keys to modify)
+ if (supportsPadding && (clip.animationClip == null || clip.animationClip.empty))
+ {
+ supportsClipIn = false;
+ }
+
+ if (supportsClipIn && !supportsPadding)
+ {
+ var minStart = clip.FromLocalTimeUnbound(0.0);
+ if (time < minStart)
+ time = minStart;
+ }
+
+ var maxStart = clip.end - TimelineClip.kMinDuration;
+ if (time > maxStart)
+ time = maxStart;
+
+ var timeOffset = time - clip.start;
+ var duration = clip.duration - timeOffset;
+
+ if (supportsClipIn)
+ {
+ if (supportsPadding)
+ {
+ double clipInGlobal = clip.clipIn / clip.timeScale;
+ double keyShift = -timeOffset;
+ if (timeOffset < 0) // left drag, eliminate clipIn before shifting
+ {
+ double clipInDelta = Math.Max(-clipInGlobal, timeOffset);
+ keyShift = -Math.Min(0, timeOffset - clipInDelta);
+ clip.clipIn += clipInDelta * clip.timeScale;
+ }
+ else if (timeOffset > 0) // right drag, elimate padding in animation clip before adding clip in
+ {
+ var clipInfo = AnimationClipCurveCache.Instance.GetCurveInfo(clip.animationClip);
+ double keyDelta = clip.FromLocalTimeUnbound(clipInfo.keyTimes.Min()) - clip.start;
+ keyShift = -Math.Max(0, Math.Min(timeOffset, keyDelta));
+ clip.clipIn += Math.Max(timeOffset + keyShift, 0) * clip.timeScale;
+ }
+ if (keyShift != 0)
+ {
+ AnimationTrackRecorder.ShiftAnimationClip(clip.animationClip, (float)(keyShift * clip.timeScale));
+ }
+ }
+ else
+ {
+ clip.clipIn += timeOffset * clip.timeScale;
+ }
+ }
+
+ clip.start = time;
+ clip.duration = duration;
+ }
+
+ public static void SetEnd(TimelineClip clip, double time, bool affectTimeScale)
+ {
+ var duration = Math.Max(time - clip.start, TimelineClip.kMinDuration);
+
+ if (affectTimeScale && clip.SupportsSpeedMultiplier())
+ {
+ var f = clip.duration / duration;
+ clip.timeScale *= f;
+ }
+
+ clip.duration = duration;
+ }
+
+ public static bool ResetEditing(TimelineClip[] clips)
+ {
+ var result = false;
+
+ foreach (var clip in clips)
+ result = result || ResetEditing(clip);
+
+ return result;
+ }
+
+ public static bool ResetEditing(TimelineClip clip)
+ {
+ if (clip.asset == null)
+ return false;
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Reset Clip Editing");
+
+ clip.clipIn = 0.0;
+
+ if (clip.clipAssetDuration < double.MaxValue)
+ {
+ var duration = clip.clipAssetDuration / clip.timeScale;
+ TrimClipWithEditMode(clip, TrimEdge.End, clip.start + duration);
+ }
+
+ return true;
+ }
+
+ public static bool MatchContent(TimelineClip[] clips)
+ {
+ var result = false;
+
+ foreach (var clip in clips)
+ result = result || MatchContent(clip);
+
+ return result;
+ }
+
+ public static bool MatchContent(TimelineClip clip)
+ {
+ if (clip.asset == null)
+ return false;
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Match Clip Content");
+
+ var newStartCandidate = clip.start - clip.clipIn / clip.timeScale;
+ var newStart = newStartCandidate < 0.0 ? 0.0 : newStartCandidate;
+
+ TrimClipWithEditMode(clip, TrimEdge.Start, newStart);
+
+ // In case resetting the start was blocked by edit mode or timeline start, we do the best we can
+ clip.clipIn = (clip.start - newStartCandidate) * clip.timeScale;
+ if (clip.clipAssetDuration > 0 && TimelineHelpers.HasUsableAssetDuration(clip))
+ {
+ var duration = TimelineHelpers.GetLoopDuration(clip);
+ var offset = (clip.clipIn / clip.timeScale) % duration;
+ TrimClipWithEditMode(clip, TrimEdge.End, clip.start - offset + duration);
+ }
+
+ return true;
+ }
+
+ public static void TrimClipWithEditMode(TimelineClip clip, TrimEdge edge, double time)
+ {
+ var clipItem = ItemsUtils.ToItem(clip);
+ EditMode.BeginTrim(clipItem, edge);
+ if (edge == TrimEdge.Start)
+ EditMode.TrimStart(clipItem, time);
+ else
+ EditMode.TrimEnd(clipItem, time, false);
+ EditMode.FinishTrim();
+ }
+
+ public static bool CompleteLastLoop(TimelineClip[] clips)
+ {
+ foreach (var clip in clips)
+ {
+ CompleteLastLoop(clip);
+ }
+
+ return true;
+ }
+
+ public static void CompleteLastLoop(TimelineClip clip)
+ {
+ FixLoops(clip, true);
+ }
+
+ public static bool TrimLastLoop(TimelineClip[] clips)
+ {
+ foreach (var clip in clips)
+ {
+ TrimLastLoop(clip);
+ }
+
+ return true;
+ }
+
+ public static void TrimLastLoop(TimelineClip clip)
+ {
+ FixLoops(clip, false);
+ }
+
+ static void FixLoops(TimelineClip clip, bool completeLastLoop)
+ {
+ if (!TimelineHelpers.HasUsableAssetDuration(clip))
+ return;
+
+ var loopDuration = TimelineHelpers.GetLoopDuration(clip);
+ var firstLoopDuration = loopDuration - clip.clipIn * (1.0 / clip.timeScale);
+
+ // Making sure we don't trim to zero
+ if (!completeLastLoop && firstLoopDuration > clip.duration)
+ return;
+
+ var numLoops = (clip.duration - firstLoopDuration) / loopDuration;
+ var numCompletedLoops = Math.Floor(numLoops);
+
+ if (!(numCompletedLoops < numLoops))
+ return;
+
+ if (completeLastLoop)
+ numCompletedLoops += 1;
+
+ var newEnd = clip.start + firstLoopDuration + loopDuration * numCompletedLoops;
+
+ TimelineUndo.PushUndo(clip.parentTrack, "Trim Clip Last Loop");
+
+ TrimClipWithEditMode(clip, TrimEdge.End, newEnd);
+ }
+
+ public static bool DoubleSpeed(TimelineClip[] clips)
+ {
+ foreach (var clip in clips)
+ {
+ if (clip.SupportsSpeedMultiplier())
+ {
+ TimelineUndo.PushUndo(clip.parentTrack, "Double Clip Speed");
+ clip.timeScale = clip.timeScale * 2.0f;
+ }
+ }
+
+ return true;
+ }
+
+ public static bool HalfSpeed(TimelineClip[] clips)
+ {
+ foreach (var clip in clips)
+ {
+ if (clip.SupportsSpeedMultiplier())
+ {
+ TimelineUndo.PushUndo(clip.parentTrack, "Half Clip Speed");
+ clip.timeScale = clip.timeScale * 0.5f;
+ }
+ }
+
+ return true;
+ }
+
+ public static bool ResetSpeed(TimelineClip[] clips)
+ {
+ foreach (var clip in clips)
+ {
+ if (clip.timeScale != 1.0)
+ {
+ TimelineUndo.PushUndo(clip.parentTrack, "Reset Clip Speed");
+ clip.timeScale = 1.0;
+ }
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs.meta
new file mode 100644
index 0000000..3fa03b9
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ClipModifier.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b0eeee3cdfa56734abca5c1a4e7989ba
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs
new file mode 100644
index 0000000..7ed3952
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs
@@ -0,0 +1,142 @@
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ class Clipboard
+ {
+ class ExposedReferenceTable : IExposedPropertyTable
+ {
+ Dictionary<PropertyName, Object> m_ReferenceTable = new Dictionary<PropertyName, Object>();
+ public void SetReferenceValue(PropertyName id, Object value)
+ {
+ m_ReferenceTable[id] = value;
+ }
+
+ public Object GetReferenceValue(PropertyName id, out bool idValid)
+ {
+ Object reference;
+ idValid = m_ReferenceTable.TryGetValue(id, out reference);
+ return reference;
+ }
+
+ public void ClearReferenceValue(PropertyName id)
+ {
+ m_ReferenceTable.Remove(id);
+ }
+
+ public void Clear()
+ {
+ m_ReferenceTable.Clear();
+ }
+ }
+
+ public struct ClipboardTrackEntry
+ {
+ public TrackAsset item;
+ public TrackAsset parent;
+ }
+
+ static readonly int kListInitialSize = 10;
+
+ readonly List<ItemsPerTrack> m_ItemsData = new List<ItemsPerTrack>(kListInitialSize);
+ readonly List<ClipboardTrackEntry> m_trackData = new List<ClipboardTrackEntry>(kListInitialSize);
+ TimelineAsset rootTimeline;
+
+ public readonly IExposedPropertyTable exposedPropertyTable = new ExposedReferenceTable();
+
+ public Clipboard()
+ {
+ rootTimeline = CreateTimeline();
+
+ EditorApplication.playModeStateChanged += OnPlayModeChanged;
+ }
+
+ public void CopyItems(IEnumerable<ITimelineItem> items)
+ {
+ using (new TimelineUndo.DisableUndoGuard(true))
+ {
+ var itemsByParent = items.ToLookup(i => i.parentTrack);
+ foreach (var itemsGroup in itemsByParent)
+ {
+ var parent = itemsGroup.Key;
+ var itemsList = new List<ITimelineItem>();
+ foreach (var item in itemsGroup)
+ {
+ if (item is ClipItem)
+ itemsList.Add(CopyItem((ClipItem)item));
+ else if (item is MarkerItem)
+ itemsList.Add(CopyItem((MarkerItem)item));
+ }
+ m_ItemsData.Add(new ItemsPerTrack(parent, itemsList));
+ }
+ }
+ }
+
+ ClipItem CopyItem(ClipItem clipItem)
+ {
+ var newClip = TimelineHelpers.Clone(clipItem.clip, TimelineWindow.instance.state.editSequence.director, exposedPropertyTable, rootTimeline);
+ return new ClipItem(newClip);
+ }
+
+ static MarkerItem CopyItem(MarkerItem markerItem)
+ {
+ var markerObject = markerItem.marker as Object;
+ if (markerObject != null)
+ {
+ var newMarker = Object.Instantiate(markerObject);
+ newMarker.name = markerObject.name;
+ return new MarkerItem((IMarker)newMarker);
+ }
+
+ return null;
+ }
+
+ public void CopyTracks(IEnumerable<TrackAsset> tracks)
+ {
+ using (new TimelineUndo.DisableUndoGuard(true))
+ {
+ foreach (var track in TrackExtensions.FilterTracks(tracks))
+ {
+ var newTrack = track.Duplicate(TimelineEditor.inspectedDirector, TimelineEditor.clipboard.exposedPropertyTable, rootTimeline);
+ m_trackData.Add(new ClipboardTrackEntry {item = newTrack, parent = track.parent as TrackAsset});
+ }
+ }
+ }
+
+ public IEnumerable<ClipboardTrackEntry> GetTracks()
+ {
+ return m_trackData;
+ }
+
+ public IEnumerable<ItemsPerTrack> GetCopiedItems()
+ {
+ return m_ItemsData;
+ }
+
+ public void Clear()
+ {
+ m_ItemsData.Clear();
+ m_trackData.Clear();
+ rootTimeline = CreateTimeline();
+ ((ExposedReferenceTable)exposedPropertyTable).Clear();
+ }
+
+ private void OnPlayModeChanged(PlayModeStateChange state)
+ {
+ if (state == PlayModeStateChange.EnteredEditMode || state == PlayModeStateChange.EnteredPlayMode)
+ Clear();
+ }
+
+ static TimelineAsset CreateTimeline()
+ {
+ var timeline = ScriptableObject.CreateInstance<TimelineAsset>();
+ timeline.hideFlags |= HideFlags.DontSave;
+ timeline.name = "Clipboard";
+
+ return timeline;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs.meta
new file mode 100644
index 0000000..af5870a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Clipboard.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b57629d89799e004182564256307b0cc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs
new file mode 100644
index 0000000..d7023e4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs
@@ -0,0 +1,62 @@
+using System.Collections.Generic;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ static class ControlPlayableUtility
+ {
+ public static bool DetectCycle(
+ ControlPlayableAsset asset, PlayableDirector director, HashSet<PlayableDirector> set = null)
+ {
+ if (director == null || asset == null || !asset.updateDirector)
+ return false;
+
+ if (set == null)
+ set = new HashSet<PlayableDirector>();
+
+ if (set.Contains(director))
+ return true;
+
+ var gameObject = asset.sourceGameObject.Resolve(director);
+ if (gameObject == null)
+ return false;
+
+ set.Add(director);
+
+ foreach (var subDirector in asset.GetComponent<PlayableDirector>(gameObject))
+ {
+ foreach (var childAsset in GetPlayableAssets(subDirector))
+ {
+ if (DetectCycle(childAsset, subDirector, set))
+ return true;
+ }
+ }
+
+ set.Remove(director);
+
+ return false;
+ }
+
+ public static IEnumerable<ControlPlayableAsset> GetPlayableAssets(PlayableDirector director)
+ {
+ var timeline = director != null ? (director.playableAsset as TimelineAsset) : null;
+ if (timeline != null)
+ {
+ foreach (var t in timeline.GetOutputTracks())
+ {
+ var controlTrack = t as ControlTrack;
+ if (controlTrack != null)
+ {
+ foreach (var c in t.GetClips())
+ {
+ var asset = c.asset as ControlPlayableAsset;
+ if (asset != null)
+ yield return asset;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs.meta
new file mode 100644
index 0000000..ab502a1
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ControlPlayableUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e801faa3b0dd2478dbe801a2441b679e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs
new file mode 100644
index 0000000..021a635
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs
@@ -0,0 +1,47 @@
+using System;
+
+namespace UnityEditor.Timeline
+{
+ // Tells a custom [[TrackDrawer]] which [[TrackAsset]] it's a drawer for.
+ sealed class CustomTrackDrawerAttribute : Attribute
+ {
+ public Type assetType;
+ public CustomTrackDrawerAttribute(Type type)
+ {
+ assetType = type;
+ }
+ }
+
+ /// <summary>
+ /// Attribute that specifies a class as an editor for an extended Timeline type.
+ /// </summary>
+ /// <remarks>
+ /// Use this attribute on a class that extends ClipEditor, TrackEditor, or MarkerEditor to specify either the PlayableAsset, Marker, or TrackAsset derived classes for associated customization.
+ /// </remarks>
+ /// <example>
+ /// [CustomTimelineEditor(typeof(LightControlClip))]
+ /// class LightControlClipEditor : ClipEditor
+ /// {
+ /// }
+ /// </example>
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
+ public sealed class CustomTimelineEditorAttribute : Attribute
+ {
+ /// <summary>
+ /// The type that that this editor applies to.
+ /// </summary>
+ public Type classToEdit { get; private set; }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="type"> The type that that this editor applies to.</param>
+ /// <exception cref="ArgumentNullException">Thrown if type is null</exception>
+ public CustomTimelineEditorAttribute(Type type)
+ {
+ if (type == null)
+ throw new System.ArgumentNullException(nameof(type));
+ classToEdit = type;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs.meta
new file mode 100644
index 0000000..1738611
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/CustomTrackDrawerAttribute.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e1e957d39ca70834f9212a1289b6a0d5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs
new file mode 100644
index 0000000..f228c4c
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs
@@ -0,0 +1,33 @@
+using System.Text;
+using UnityEngine.Playables;
+
+namespace UnityEditor.Timeline
+{
+ static class DisplayNameHelper
+ {
+ static readonly string k_NoAssetDisplayName = L10n.Tr("<No Asset>");
+ static readonly string k_ReadOnlyDisplayName = L10n.Tr("[Read Only]");
+ static readonly StringBuilder k_StringBuilder = new StringBuilder();
+
+ public static string GetDisplayName(ISequenceState sequence)
+ {
+ string displayName = sequence.director != null ? GetDisplayName(sequence.director) : GetDisplayName(sequence.asset);
+ if (sequence.asset != null && sequence.isReadOnly)
+ displayName += " " + k_ReadOnlyDisplayName;
+ return displayName;
+ }
+
+ public static string GetDisplayName(PlayableAsset asset)
+ {
+ return asset != null ? asset.name : k_NoAssetDisplayName;
+ }
+
+ public static string GetDisplayName(PlayableDirector director)
+ {
+ k_StringBuilder.Length = 0;
+ k_StringBuilder.Append(GetDisplayName(director.playableAsset));
+ k_StringBuilder.Append(" (").Append(director.name).Append(')');
+ return k_StringBuilder.ToString();
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs.meta
new file mode 100644
index 0000000..cb233c8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/DisplayNameHelper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7fc2147e42d71644aad0eaf9a3526249
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs
new file mode 100644
index 0000000..47815cd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs
@@ -0,0 +1,21 @@
+using System;
+using UnityEngine;
+
+namespace UnityEditor.Timeline
+{
+ struct GUIColorOverride : IDisposable
+ {
+ readonly Color m_OldColor;
+
+ public GUIColorOverride(Color newColor)
+ {
+ m_OldColor = GUI.color;
+ GUI.color = newColor;
+ }
+
+ public void Dispose()
+ {
+ GUI.color = m_OldColor;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs.meta
new file mode 100644
index 0000000..1d338af
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIColorOverride.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 44507a833d0ca8a42aaec1c3d752eb5f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs
new file mode 100644
index 0000000..e8f0413
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs
@@ -0,0 +1,18 @@
+using System;
+using UnityEngine;
+
+namespace UnityEditor
+{
+ struct GUIGroupScope : IDisposable
+ {
+ public GUIGroupScope(Rect position)
+ {
+ GUI.BeginGroup(position);
+ }
+
+ public void Dispose()
+ {
+ GUI.EndGroup();
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs.meta
new file mode 100644
index 0000000..d0a2d09
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIGroupScope.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0bee8aba5e8a40446b7098666c5314d9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs
new file mode 100644
index 0000000..f3da9f3
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs
@@ -0,0 +1,20 @@
+using System;
+using UnityEngine;
+
+namespace UnityEditor
+{
+ struct GUIMixedValueScope : IDisposable
+ {
+ readonly bool m_PrevValue;
+ public GUIMixedValueScope(bool newValue)
+ {
+ m_PrevValue = EditorGUI.showMixedValue;
+ EditorGUI.showMixedValue = newValue;
+ }
+
+ public void Dispose()
+ {
+ EditorGUI.showMixedValue = m_PrevValue;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs.meta
new file mode 100644
index 0000000..94ff586
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIMixedValueScope.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d59cefc45e3c31d4a90563364e7258fa
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs
new file mode 100644
index 0000000..7999ffd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs
@@ -0,0 +1,34 @@
+using System;
+using UnityEngine;
+
+namespace UnityEditor
+{
+ // Special Clip Scope that only effects painting, and keeps the coordinate system identical
+ struct GUIViewportScope : IDisposable
+ {
+ bool m_open;
+ public GUIViewportScope(Rect position)
+ {
+ m_open = false;
+ if (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout)
+ {
+ GUI.BeginClip(position, -position.min, Vector2.zero, false);
+ m_open = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ CloseScope();
+ }
+
+ void CloseScope()
+ {
+ if (m_open)
+ {
+ GUI.EndClip();
+ m_open = false;
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs.meta
new file mode 100644
index 0000000..1c3a2f0
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/GUIViewportScope.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: af84cf39b8fa0654badd9278cbd00d77
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs
new file mode 100644
index 0000000..cc9addf
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs
@@ -0,0 +1,109 @@
+using UnityEngine;
+
+namespace UnityEditor.Timeline
+{
+ static class Graphics
+ {
+ public static void ShadowLabel(Rect rect, string text, GUIStyle style, Color textColor, Color shadowColor)
+ {
+ ShadowLabel(rect, GUIContent.Temp(text), style, textColor, shadowColor);
+ }
+
+ public static void ShadowLabel(Rect rect, GUIContent content, GUIStyle style, Color textColor, Color shadowColor)
+ {
+ var shadowRect = rect;
+ shadowRect.xMin += 2.0f;
+ shadowRect.yMin += 2.0f;
+ style.normal.textColor = Color.black;
+ GUI.Label(shadowRect, content, style);
+
+ style.normal.textColor = textColor;
+ GUI.Label(rect, content, style);
+ }
+
+ public static void DrawLine(Vector3 p1, Vector3 p2, Color color)
+ {
+ var c = Handles.color;
+ Handles.color = color;
+ Handles.DrawLine(p1, p2);
+ Handles.color = c;
+ }
+
+ public static void DrawPolygonAA(Color color, Vector3[] vertices)
+ {
+ var prevColor = Handles.color;
+ Handles.color = color;
+ Handles.DrawAAConvexPolygon(vertices);
+ Handles.color = prevColor;
+ }
+
+ public static void DrawDottedLine(Vector3 p1, Vector3 p2, float segmentsLength, Color col)
+ {
+ HandleUtility.ApplyWireMaterial();
+
+ GL.Begin(GL.LINES);
+ GL.Color(col);
+
+ var length = Vector3.Distance(p1, p2); // ignore z component
+ var count = Mathf.CeilToInt(length / segmentsLength);
+ for (var i = 0; i < count; i += 2)
+ {
+ GL.Vertex((Vector3.Lerp(p1, p2, i * segmentsLength / length)));
+ GL.Vertex((Vector3.Lerp(p1, p2, (i + 1) * segmentsLength / length)));
+ }
+
+ GL.End();
+ }
+
+ public static void DrawLineAtTime(WindowState state, double time, Color color, bool dotted = false)
+ {
+ var t = state.TimeToPixel(time);
+
+ var p0 = new Vector3(t, state.timeAreaRect.yMax);
+ var p1 = new Vector3(t, state.timeAreaRect.yMax + state.windowHeight - WindowConstants.sliderWidth);
+
+ if (dotted)
+ DrawDottedLine(p0, p1, 4.0f, color);
+ else
+ DrawLine(p0, p1, color);
+ }
+
+ public static void DrawTextureRepeated(Rect area, Texture texture)
+ {
+ if (texture == null || Event.current.type != EventType.Repaint)
+ return;
+
+ GUI.BeginClip(area);
+ int w = Mathf.CeilToInt(area.width / texture.width);
+ int h = Mathf.CeilToInt(area.height / texture.height);
+ for (int x = 0; x < w; x++)
+ {
+ for (int y = 0; y < h; y++)
+ {
+ GUI.DrawTexture(new Rect(x * texture.width, y * texture.height, texture.width, texture.height), texture);
+ }
+ }
+
+ GUI.EndClip();
+ }
+
+ public static void DrawShadow(Rect clientRect)
+ {
+ var rect = clientRect;
+ rect.height = WindowConstants.shadowUnderTimelineHeight;
+ GUI.Box(rect, GUIContent.none, DirectorStyles.Instance.bottomShadow);
+ }
+
+ public static void DrawBackgroundRect(WindowState state, Rect rect, bool subSequenceMode = false)
+ {
+ Color c = subSequenceMode ? DirectorStyles.Instance.customSkin.colorSubSequenceBackground : DirectorStyles.Instance.customSkin.colorSequenceBackground;
+ EditorGUI.DrawRect(rect, c);
+ if (state.IsEditingAPrefabAsset())
+ {
+ c = SceneView.kSceneViewPrefabBackground.Color;
+ c.a = 0.5f;
+ EditorGUI.DrawRect(rect, c);
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs.meta
new file mode 100644
index 0000000..72bcc8d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Graphics.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4545bb65ccebf8040ac212d5792979b5
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs
new file mode 100644
index 0000000..2f64868
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs
@@ -0,0 +1,203 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline.Utilities
+{
+ class KeyTraverser
+ {
+ float[] m_KeyCache;
+ int m_DirtyStamp = -1;
+ int m_LastHash = -1;
+ readonly TimelineAsset m_Asset;
+ readonly float m_Epsilon;
+ int m_LastIndex = -1;
+
+ public int lastIndex
+ {
+ get { return m_LastIndex; }
+ }
+
+ public static IEnumerable<float> GetClipKeyTimes(TimelineClip clip)
+ {
+ if (clip == null || clip.animationClip == null || clip.animationClip.empty)
+ return new float[0];
+
+ return AnimationClipCurveCache.Instance.GetCurveInfo(clip.animationClip).keyTimes.
+ Select(k => (float)clip.FromLocalTimeUnbound(k)). // convert to sequence time
+ Where(k => k >= clip.start && k <= clip.end); // remove non visible keys
+ }
+
+ public static IEnumerable<float> GetTrackKeyTimes(AnimationTrack track)
+ {
+ if (track != null)
+ {
+ if (track.inClipMode)
+ return track.clips.Where(c => c.recordable).
+ SelectMany(x => GetClipKeyTimes(x));
+ if (track.infiniteClip != null && !track.infiniteClip.empty)
+ return AnimationClipCurveCache.Instance.GetCurveInfo(track.infiniteClip).keyTimes;
+ }
+ return new float[0];
+ }
+
+ static int CalcAnimClipHash(TrackAsset asset)
+ {
+ int hash = 0;
+ if (asset != null)
+ {
+ AnimationTrack animTrack = asset as AnimationTrack;
+ if (animTrack != null)
+ {
+ for (var i = 0; i != animTrack.clips.Length; ++i)
+ {
+ hash ^= (animTrack.clips[i]).Hash();
+ }
+ }
+ foreach (var subTrack in asset.GetChildTracks())
+ {
+ if (subTrack != null)
+ hash ^= CalcAnimClipHash(subTrack);
+ }
+ }
+ return hash;
+ }
+
+ internal static int CalcAnimClipHash(TimelineAsset asset)
+ {
+ int hash = 0;
+ foreach (var t in asset.GetRootTracks())
+ {
+ if (t != null)
+ hash ^= CalcAnimClipHash(t);
+ }
+ return hash;
+ }
+
+ void RebuildKeyCache()
+ {
+ m_KeyCache = m_Asset.flattenedTracks.Where(x => (x as AnimationTrack) != null)
+ .Cast<AnimationTrack>()
+ .SelectMany(t => GetTrackKeyTimes(t)).
+ OrderBy(x => x).ToArray();
+
+ if (m_KeyCache.Length > 0)
+ {
+ float[] unique = new float[m_KeyCache.Length];
+ unique[0] = m_KeyCache[0];
+ int index = 0;
+ for (int i = 1; i < m_KeyCache.Length; i++)
+ {
+ if (m_KeyCache[i] - unique[index] > m_Epsilon)
+ {
+ index++;
+ unique[index] = m_KeyCache[i];
+ }
+ }
+ m_KeyCache = unique;
+ Array.Resize(ref m_KeyCache, index + 1);
+ }
+ }
+
+ public KeyTraverser(TimelineAsset timeline, float epsilon)
+ {
+ m_Asset = timeline;
+ m_Epsilon = epsilon;
+ }
+
+ void CheckCache(int dirtyStamp)
+ {
+ int hash = CalcAnimClipHash(m_Asset);
+ if (dirtyStamp != m_DirtyStamp || hash != m_LastHash)
+ {
+ RebuildKeyCache();
+ m_DirtyStamp = dirtyStamp;
+ m_LastHash = hash;
+ }
+ }
+
+ public float GetNextKey(float key, int dirtyStamp)
+ {
+ CheckCache(dirtyStamp);
+ if (m_KeyCache.Length > 0)
+ {
+ if (key < m_KeyCache.Last() - m_Epsilon)
+ {
+ if (key > m_KeyCache[0] - m_Epsilon)
+ {
+ float t = key + m_Epsilon;
+ // binary search
+ int max = m_KeyCache.Length - 1;
+ int min = 0;
+ while (max - min > 1)
+ {
+ int imid = (min + max) / 2;
+ if (t > m_KeyCache[imid])
+ min = imid;
+ else
+ max = imid;
+ }
+ m_LastIndex = max;
+ return m_KeyCache[max];
+ }
+
+ m_LastIndex = 0;
+ return m_KeyCache[0];
+ }
+ if (key < m_KeyCache.Last() + m_Epsilon)
+ {
+ m_LastIndex = m_KeyCache.Length - 1;
+ return Mathf.Max(key, m_KeyCache.Last());
+ }
+ }
+ m_LastIndex = -1;
+ return key;
+ }
+
+ public float GetPrevKey(float key, int dirtyStamp)
+ {
+ CheckCache(dirtyStamp);
+ if (m_KeyCache.Length > 0)
+ {
+ if (key > m_KeyCache[0] + m_Epsilon)
+ {
+ if (key < m_KeyCache.Last() + m_Epsilon)
+ {
+ float t = key - m_Epsilon;
+
+ // binary search
+ int max = m_KeyCache.Length - 1;
+ int min = 0;
+ while (max - min > 1)
+ {
+ int imid = (min + max) / 2;
+ if (t < m_KeyCache[imid])
+ max = imid;
+ else
+ min = imid;
+ }
+ m_LastIndex = min;
+ return m_KeyCache[min];
+ }
+ m_LastIndex = m_KeyCache.Length - 1;
+ return m_KeyCache.Last();
+ }
+ if (key >= m_KeyCache[0] - m_Epsilon)
+ {
+ m_LastIndex = 0;
+ return Mathf.Min(key, m_KeyCache[0]);
+ }
+ }
+ m_LastIndex = -1;
+ return key;
+ }
+
+ public int GetKeyCount(int dirtyStamp)
+ {
+ CheckCache(dirtyStamp);
+ return m_KeyCache.Length;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs.meta
new file mode 100644
index 0000000..5ce97aa
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/KeyTraverser.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4b57f909f22642d469a39e9628535312
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs
new file mode 100644
index 0000000..9da5277
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+using Object = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ static class MarkerModifier
+ {
+ public static void DeleteMarker(IMarker marker)
+ {
+ var trackAsset = marker.parent;
+ if (trackAsset != null)
+ {
+ SelectionManager.Remove(marker);
+ trackAsset.DeleteMarker(marker);
+ }
+ }
+
+ public static IEnumerable<IMarker> CloneMarkersToParent(IEnumerable<IMarker> markers, TrackAsset parent)
+ {
+ if (!markers.Any()) return Enumerable.Empty<IMarker>();
+ var clonedMarkers = new List<IMarker>();
+ foreach (var marker in markers)
+ clonedMarkers.Add(CloneMarkerToParent(marker, parent));
+ return clonedMarkers;
+ }
+
+ public static IMarker CloneMarkerToParent(IMarker marker, TrackAsset parent)
+ {
+ var markerObject = marker as ScriptableObject;
+ if (markerObject == null) return null;
+
+ var newMarkerObject = Object.Instantiate(markerObject);
+ AddMarkerToParent(newMarkerObject, parent);
+
+ newMarkerObject.name = markerObject.name;
+ try
+ {
+ CustomTimelineEditorCache.GetMarkerEditor((IMarker)newMarkerObject).OnCreate((IMarker)newMarkerObject, marker);
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e);
+ }
+
+
+ return (IMarker)newMarkerObject;
+ }
+
+ static void AddMarkerToParent(ScriptableObject marker, TrackAsset parent)
+ {
+ TimelineCreateUtilities.SaveAssetIntoObject(marker, parent);
+ TimelineUndo.RegisterCreatedObjectUndo(marker, "Duplicate Marker");
+ TimelineUndo.PushUndo(parent, "Duplicate Marker");
+
+ if (parent != null)
+ {
+ parent.AddMarker(marker);
+ ((IMarker)marker).Initialize(parent);
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs.meta
new file mode 100644
index 0000000..b16c6f5
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/MarkerModifier.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7cfaad4e53832d94c9421d2dd1ad82f7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs
new file mode 100644
index 0000000..863500d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs
@@ -0,0 +1,28 @@
+using UnityEngine;
+using UnityEditor;
+
+namespace UnityEditor.Timeline
+{
+ static class ObjectExtension
+ {
+ public static bool IsSceneObject(this Object obj)
+ {
+ if (obj == null)
+ return false;
+
+ bool isSceneType = obj is GameObject || obj is Component;
+ if (!isSceneType)
+ return false;
+
+ return !PrefabUtility.IsPartOfPrefabAsset(obj);
+ }
+
+ public static bool IsPrefab(this Object obj)
+ {
+ if (obj == null)
+ return false;
+
+ return PrefabUtility.IsPartOfPrefabAsset(obj);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs.meta
new file mode 100644
index 0000000..b1ff382
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectExtension.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4722a1362908a1843ab03a055c5c3fa0
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs
new file mode 100644
index 0000000..3ace197
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using UnityEngine;
+using UnityEngine.Timeline;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using UnityEngine.Playables;
+using Object = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ // Describes the object references on a ScriptableObject, ignoring script fields
+ struct ObjectReferenceField
+ {
+ public string propertyPath;
+ public bool isSceneReference;
+ public System.Type type;
+
+ private readonly static ObjectReferenceField[] None = new ObjectReferenceField[0];
+ private readonly static Dictionary<System.Type, ObjectReferenceField[]> s_Cache = new Dictionary<System.Type, ObjectReferenceField[]>();
+
+ public static ObjectReferenceField[] FindObjectReferences(System.Type type)
+ {
+ if (type == null)
+ return None;
+
+ if (type.IsAbstract || type.IsInterface)
+ return None;
+
+ if (!typeof(ScriptableObject).IsAssignableFrom(type))
+ return None;
+
+ ObjectReferenceField[] result = null;
+ if (s_Cache.TryGetValue(type, out result))
+ return result;
+
+ result = SearchForFields(type);
+ s_Cache[type] = result;
+ return result;
+ }
+
+ public static ObjectReferenceField[] FindObjectReferences<T>() where T : ScriptableObject, new()
+ {
+ return FindObjectReferences(typeof(T));
+ }
+
+ private static ObjectReferenceField[] SearchForFields(System.Type t)
+ {
+ Object instance = ScriptableObject.CreateInstance(t);
+ var list = new List<ObjectReferenceField>();
+
+ var serializableObject = new SerializedObject(instance);
+ var prop = serializableObject.GetIterator();
+ bool enterChildren = true;
+ while (prop.NextVisible(enterChildren))
+ {
+ enterChildren = true;
+ var ppath = prop.propertyPath;
+ if (ppath == "m_Script")
+ {
+ enterChildren = false;
+ }
+ else if (prop.propertyType == SerializedPropertyType.ObjectReference || prop.propertyType == SerializedPropertyType.ExposedReference)
+ {
+ enterChildren = false;
+ var exposedType = GetTypeFromPath(t, prop.propertyPath);
+ if (exposedType != null && typeof(Object).IsAssignableFrom(exposedType))
+ {
+ bool isSceneRef = prop.propertyType == SerializedPropertyType.ExposedReference;
+ list.Add(
+ new ObjectReferenceField() {propertyPath = prop.propertyPath, isSceneReference = isSceneRef, type = exposedType}
+ );
+ }
+ }
+ }
+
+ Object.DestroyImmediate(instance);
+ if (list.Count == 0)
+ return None;
+ return list.ToArray();
+ }
+
+ private static System.Type GetTypeFromPath(System.Type baseType, string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ return null;
+
+ System.Type parentType = baseType;
+ FieldInfo field = null;
+ var pathTo = path.Split(new char[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
+ var flags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.Instance;
+ foreach (string s in pathTo)
+ {
+ field = parentType.GetField(s, flags);
+ while (field == null)
+ {
+ if (parentType.BaseType == null)
+ return null; // Should not happen really. Means SerializedObject got the property, but the reflection missed it
+ parentType = parentType.BaseType;
+ field = parentType.GetField(s, flags);
+ }
+
+ parentType = field.FieldType;
+ }
+
+ // dig out exposed reference types
+ if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(ExposedReference<Object>).GetGenericTypeDefinition())
+ {
+ return field.FieldType.GetGenericArguments()[0];
+ }
+
+ return field.FieldType;
+ }
+
+ public Object Find(ScriptableObject sourceObject, Object context = null)
+ {
+ if (sourceObject == null)
+ return null;
+
+ SerializedObject obj = new SerializedObject(sourceObject, context);
+ var prop = obj.FindProperty(propertyPath);
+ if (prop == null)
+ throw new InvalidOperationException("sourceObject is not of the proper type. It does not contain a path to " + propertyPath);
+
+ Object result = null;
+ if (isSceneReference)
+ {
+ if (prop.propertyType != SerializedPropertyType.ExposedReference)
+ throw new InvalidOperationException(propertyPath + " is marked as a Scene Reference, but is not an exposed reference type");
+ if (context == null)
+ Debug.LogWarning("ObjectReferenceField.Find " + " is called on a scene reference without a context, will always be null");
+
+ result = prop.exposedReferenceValue;
+ }
+ else
+ {
+ if (prop.propertyType != SerializedPropertyType.ObjectReference)
+ throw new InvalidOperationException(propertyPath + "is marked as an asset reference, but is not an object reference type");
+ result = prop.objectReferenceValue;
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Check if an Object satisfies this field, including components
+ /// </summary>
+ public bool IsAssignable(Object obj)
+ {
+ if (obj == null)
+ return false;
+
+ // types match
+ bool potentialMatch = type.IsAssignableFrom(obj.GetType());
+
+ // field is component, and it exists on the gameObject
+ if (!potentialMatch && typeof(Component).IsAssignableFrom(type) && obj is GameObject)
+ potentialMatch = ((GameObject)obj).GetComponent(type) != null;
+
+ return potentialMatch && isSceneReference == obj.IsSceneObject();
+ }
+
+ /// <summary>
+ /// Assigns a value to the field
+ /// </summary>
+ public bool Assign(ScriptableObject scriptableObject, Object value, IExposedPropertyTable exposedTable = null)
+ {
+ var serializedObject = new SerializedObject(scriptableObject, exposedTable as Object);
+ var property = serializedObject.FindProperty(propertyPath);
+ if (property == null)
+ return false;
+
+ // if the value is a game object, but the field is a component
+ if (value is GameObject && typeof(Component).IsAssignableFrom(type))
+ value = ((GameObject)value).GetComponent(type);
+
+ if (isSceneReference)
+ {
+ property.exposedReferenceValue = value;
+
+ // the object gets dirtied, but not the scene which is where the reference is stored
+ var component = exposedTable as Component;
+ if (component != null && !EditorApplication.isPlaying)
+ EditorSceneManager.MarkSceneDirty(component.gameObject.scene);
+ }
+ else
+ property.objectReferenceValue = value;
+
+ serializedObject.ApplyModifiedProperties();
+ return true;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs.meta
new file mode 100644
index 0000000..c0655c7
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/ObjectReferenceField.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 29bf1d4ec1012bc45967ce95b729b8b3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs
new file mode 100644
index 0000000..f19300d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs
@@ -0,0 +1,226 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using Object = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ class PropertyCollector : IPropertyCollector
+ {
+ readonly Stack<GameObject> m_ObjectStack = new Stack<GameObject>();
+
+ // Call immediately before use
+ public void Reset()
+ {
+ m_ObjectStack.Clear();
+ }
+
+ // call to reset caches. should be called when switching master timelines
+ public void Clear()
+ {
+ m_ObjectStack.Clear();
+ AnimationPreviewUtilities.ClearCaches();
+ }
+
+ public void PushActiveGameObject(GameObject gameObject)
+ {
+ m_ObjectStack.Push(gameObject);
+ }
+
+ public void PopActiveGameObject()
+ {
+ m_ObjectStack.Pop();
+ }
+
+ public void AddFromClip(AnimationClip clip)
+ {
+ var go = m_ObjectStack.Peek(); // allow it to throw if empty
+ if (go != null && clip != null) // null game object is allowed for calls to be ignored
+ AddFromClip(go, clip);
+ }
+
+ public void AddFromClips(IEnumerable<AnimationClip> clips)
+ {
+ var go = m_ObjectStack.Peek();
+ if (go != null)
+ AddFromClips(go, clips);
+ }
+
+ public void AddFromName<T>(string name) where T : Component
+ {
+ var go = m_ObjectStack.Peek(); // allow it to throw if empty
+ if (go != null) // null game object is allowed for calls to be ignored
+ AddFromName<T>(go, name);
+ }
+
+ public void AddFromName(string name)
+ {
+ var go = m_ObjectStack.Peek(); // allow it to throw if empty
+ if (go != null) // null game object is allowed for calls to be ignored
+ AddFromName(go, name);
+ }
+
+ public void AddFromClip(GameObject obj, AnimationClip clip)
+ {
+ if (!Application.isPlaying)
+ AddPropertiesFromClip(obj, clip);
+ }
+
+ public void AddFromClips(GameObject animatorRoot, IEnumerable<AnimationClip> clips)
+ {
+ if (Application.isPlaying)
+ return;
+
+ AnimationPreviewUtilities.PreviewFromCurves(animatorRoot, AnimationPreviewUtilities.GetBindings(animatorRoot, clips));
+ }
+
+ public void AddFromName<T>(GameObject obj, string name) where T : Component
+ {
+ if (!Application.isPlaying)
+ AddPropertiesFromName(obj, typeof(T), name);
+ }
+
+ public void AddFromName(GameObject obj, string name)
+ {
+ if (!Application.isPlaying)
+ AddPropertiesFromName(obj, name);
+ }
+
+ public void AddFromName(Component component, string name)
+ {
+ if (!Application.isPlaying)
+ AddPropertyModification(component, name);
+ }
+
+ public void AddFromComponent(GameObject obj, Component component)
+ {
+ if (Application.isPlaying)
+ return;
+
+ if (obj == null || component == null)
+ return;
+
+ var serializedObject = new SerializedObject(component);
+ SerializedProperty property = serializedObject.GetIterator();
+
+ while (property.NextVisible(true))
+ {
+ if (property.hasVisibleChildren || !AnimatedParameterUtility.IsTypeAnimatable(property.propertyType))
+ continue;
+
+ AddPropertyModification(component, property.propertyPath);
+ }
+ }
+
+ void AddPropertiesFromClip(GameObject go, AnimationClip clip)
+ {
+ if (go != null && clip != null)
+ {
+ AnimationMode.InitializePropertyModificationForGameObject(go, clip);
+ }
+ }
+
+ static void AddPropertiesFromName(GameObject go, string property)
+ {
+ if (go == null)
+ return;
+
+ AddPropertyModification(go, property);
+ }
+
+ static void AddPropertiesFromName(GameObject go, Type compType, string property)
+ {
+ if (go == null)
+ return;
+ var comp = go.GetComponent(compType);
+ if (comp == null)
+ return;
+
+ AddPropertyModification(comp, property);
+ }
+
+ public void AddObjectProperties(Object obj, AnimationClip clip)
+ {
+ if (obj == null || clip == null)
+ return;
+
+ IPlayableAsset asset = obj as IPlayableAsset;
+ IPlayableBehaviour playable = obj as IPlayableBehaviour;
+
+ // special case for assets that contain animated script playables.
+ // The paths in the clip start from the field with the templated playable
+ if (asset != null)
+ {
+ if (playable == null)
+ {
+ AddSerializedPlayableModifications(asset, clip);
+ }
+ else
+ {
+ // in this case the asset is the playable. The clip applies directly
+ AnimationMode.InitializePropertyModificationForObject(obj, clip);
+ }
+ }
+ }
+
+ void AddSerializedPlayableModifications(IPlayableAsset asset, AnimationClip clip)
+ {
+ var obj = asset as Object;
+ if (obj == null)
+ return;
+
+ var driver = WindowState.previewDriver;
+ if (driver == null || !AnimationMode.InAnimationMode(driver))
+ return;
+
+ var serializedObj = new SerializedObject(obj);
+ var bindings = AnimationClipCurveCache.Instance.GetCurveInfo(clip).bindings;
+ var fields = AnimatedParameterUtility.GetScriptPlayableFields(asset);
+
+ // go through each binding and offset using the field name
+ // so the modification system can find the particle object using the asset as a root
+ foreach (var b in bindings)
+ {
+ foreach (var f in fields)
+ {
+ var propertyPath = f.Name + "." + b.propertyName;
+ if (serializedObj.FindProperty(propertyPath) != null)
+ {
+ DrivenPropertyManager.RegisterProperty(driver, obj, propertyPath);
+ break;
+ }
+ }
+ }
+ }
+
+ private static void AddPropertyModification(GameObject obj, string propertyName)
+ {
+ var driver = WindowState.previewDriver;
+ if (driver == null || !AnimationMode.InAnimationMode(driver))
+ return;
+
+ DrivenPropertyManager.RegisterProperty(driver, obj, propertyName);
+ }
+
+ private static void AddPropertyModification(Component comp, string name)
+ {
+ if (comp == null)
+ return;
+
+ var driver = WindowState.previewDriver;
+ if (driver == null || !AnimationMode.InAnimationMode(driver))
+ return;
+
+ // Register Property will display an error if a property doesn't exist (wanted behaviour)
+ // However, it also displays an error on Monobehaviour m_Script property, since it can't be driven. (not wanted behaviour)
+ // case 967026
+ if (name == "m_Script" && (comp as MonoBehaviour) != null)
+ return;
+
+ DrivenPropertyManager.RegisterProperty(driver, comp, name);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs.meta
new file mode 100644
index 0000000..3e8f486
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/PropertyCollector.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1f3a562675833b4448299e4f627b0cec
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs
new file mode 100644
index 0000000..745e742
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs
@@ -0,0 +1,49 @@
+using System;
+using UnityEngine;
+
+namespace UnityEditor.Timeline
+{
+ struct Range
+ {
+ public double start;
+ public double end;
+ public double length { get { return end - start; } }
+
+ public static Range Union(Range lhs, Range rhs)
+ {
+ return new Range
+ {
+ start = Math.Min(lhs.start, rhs.start),
+ end = Math.Max(lhs.end, rhs.end)
+ };
+ }
+
+ public static Range Intersection(Range lhs, Range rhs)
+ {
+ var s = Math.Max(lhs.start, rhs.start);
+ var e = Math.Min(lhs.end, rhs.end);
+
+ if (s > e)
+ {
+ // No intersection returns a 0-length range from 0 to 0
+ return new Range();
+ }
+
+ return new Range
+ {
+ start = s,
+ end = e
+ };
+ }
+
+ public override string ToString()
+ {
+ return ToString("F3");
+ }
+
+ public string ToString(string format)
+ {
+ return UnityString.Format("({0}, {1})", start.ToString(format), end.ToString(format));
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs.meta
new file mode 100644
index 0000000..22005c4
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/Range.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d31dfeaa131921f4eae00783cc48146f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs
new file mode 100644
index 0000000..654eecb
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+
+namespace UnityEditor.Timeline
+{
+ // Class used for uniquely format names used in the GenericMenu. We can't add duplicate MenuItem in GenericMenu
+ // so that's why we need to keep information about the text we want to uniquely format.
+ class SequenceMenuNameFormater
+ {
+ Dictionary<int, int> m_UniqueItem = new Dictionary<int, int>();
+
+ public string Format(string text)
+ {
+ var key = text.GetHashCode();
+ var index = 0;
+
+ if (m_UniqueItem.ContainsKey(key))
+ {
+ index = m_UniqueItem[key];
+ index++;
+ m_UniqueItem[key] = index;
+ }
+ else
+ {
+ m_UniqueItem.Add(key, index);
+ return text;
+ }
+
+ return $"{text}{index}";
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs.meta
new file mode 100644
index 0000000..9fe16bd
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SequenceSelectorNameFormater.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1861286ba69badd439188a65bebf3cda
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs
new file mode 100644
index 0000000..1539a1d
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ interface IBounds
+ {
+ Rect boundingRect { get; }
+ }
+
+ class SpacePartitioner
+ {
+ internal class CachedList<T>
+ {
+ public static readonly List<T> Instance = new List<T>(1000);
+ }
+
+ struct Entry : IInterval
+ {
+ public object item { get; set; }
+ public long intervalStart { get; set; }
+ public long intervalEnd { get; set; }
+ public Rect bounds { get; set; }
+
+ private const float kPrecision = 100.0f;
+ private const float kMaxFloat = (float)long.MaxValue;
+ private const float kMinFloat = (float)long.MinValue;
+
+ static public Int64 FromFloat(float f)
+ {
+ if (Single.IsPositiveInfinity(f))
+ return long.MaxValue;
+ if (Single.IsNegativeInfinity(f))
+ return long.MinValue;
+
+ f = Mathf.Clamp(f, kMinFloat, kMaxFloat); // prevent overflow of floats
+ f = Mathf.Clamp(f * kPrecision, kMinFloat, kMaxFloat); // clamp to 'long' range
+ return (long)(f);
+ }
+ }
+
+ const EventType k_GuiEventLock = EventType.Repaint;
+
+ IntervalTree<Entry> m_Tree = new IntervalTree<Entry>();
+ List<Entry> m_CacheList = new List<Entry>();
+
+ public void Clear()
+ {
+ m_Tree.Clear();
+ }
+
+ public void AddBounds(IBounds bounds)
+ {
+ AddBounds(bounds, bounds.boundingRect);
+ }
+
+ public void AddBounds(object item, Rect rect)
+ {
+ if (item == null)
+ throw new ArgumentNullException("item");
+
+ m_Tree.Add(new Entry()
+ {
+ intervalStart = Entry.FromFloat(rect.yMin),
+ intervalEnd = Entry.FromFloat(rect.yMax),
+ bounds = rect,
+ item = item
+ }
+ );
+ }
+
+ /// <summary>
+ /// Get items of type T at a given position
+ /// </summary>
+ /// <param name="position"></param>
+ /// <param name="inClipSpace"></param>
+ /// <typeparam name="T"></typeparam>
+ /// <remarks>
+ /// Uses a (1,1) sized box
+ /// Use .ToList() or .ToArray() when not enumerating the result immediately
+ /// </remarks>
+ /// <returns></returns>
+ public IEnumerable<T> GetItemsAtPosition<T>(Vector2 position)
+ {
+ return GetItemsInArea<T>(new Rect(position.x, position.y, 1, 1));
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="area"></param>
+ /// <param name="inClipSpace"></param>
+ /// <typeparam name="T"></typeparam>
+ /// <returns></returns>
+ public IEnumerable<T> GetItemsInArea<T>(Rect area)
+ {
+ m_CacheList.Clear();
+ m_Tree.IntersectsWithRange(long.MinValue, long.MaxValue, m_CacheList);
+
+ var list = CachedList<T>.Instance;
+ list.Clear();
+ foreach (var i in m_CacheList)
+ {
+ if (i.item is T && i.bounds.Overlaps(area))
+ list.Add((T)i.item);
+ }
+ return list;
+ }
+
+ public void DebugDraw()
+ {
+ var kFillColor = new Color(1.0f, 1.0f, 1.0f, 0.1f);
+ var kOutlineColor = Color.yellow;
+
+ m_CacheList.Clear();
+ m_Tree.IntersectsWithRange(long.MinValue, long.MaxValue, m_CacheList);
+ HandleUtility.ApplyWireMaterial();
+
+ foreach (var item in m_CacheList)
+ {
+ Handles.DrawSolidRectangleWithOutline(item.bounds, kFillColor, kOutlineColor);
+ }
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs.meta
new file mode 100644
index 0000000..2359cae
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/SpacePartitioner.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2fa2cf7de51b0d34d9dce3747b72e49d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs
new file mode 100644
index 0000000..794fc68
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor.Experimental;
+using UnityEditor.StyleSheets;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ static class StyleManager
+ {
+ static readonly StyleState[] k_StyleStates = { StyleState.any };
+ static readonly string k_ErrorCannotFindStyle = L10n.Tr("Cannot find style {0} for {1}");
+
+ static Dictionary<Type, GUIStyle> s_CustomStyles = new Dictionary<Type, GUIStyle>();
+ static GUISkin s_CurrentSkin;
+
+ public static GUIStyle UssStyleForType(Type type)
+ {
+ ClearCacheIfInvalid();
+
+ GUIStyle cachedStyle;
+ if (s_CustomStyles.TryGetValue(type, out cachedStyle))
+ return cachedStyle;
+
+ var style = DirectorStyles.GetGUIStyle(DirectorStyles.markerDefaultStyle);
+
+ var customStyleForType = CustomStyleForType(type);
+ if (customStyleForType != null)
+ {
+ if (IsStyleValid(customStyleForType))
+ style = DirectorStyles.GetGUIStyle(customStyleForType);
+ else
+ Debug.LogWarningFormat(k_ErrorCannotFindStyle, customStyleForType, type.Name);
+ }
+
+ s_CustomStyles.Add(type, style);
+ return style;
+ }
+
+ static string CustomStyleForType(Type type)
+ {
+ var attr = (CustomStyleAttribute)type.GetCustomAttributes(typeof(CustomStyleAttribute), true).FirstOrDefault();
+ return attr != null ? attr.ussStyle : null;
+ }
+
+ static bool IsStyleValid(string ussStyle)
+ {
+ return GUISkin.current.FindStyle(ussStyle) != null || EditorResources.styleCatalog.GetStyle(ussStyle, k_StyleStates).IsValid();
+ }
+
+ static void ClearCacheIfInvalid()
+ {
+ if (s_CurrentSkin != GUISkin.current)
+ s_CustomStyles.Clear();
+ s_CurrentSkin = GUISkin.current;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs.meta
new file mode 100644
index 0000000..bba0d35
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5f31f28cc64c91042976555c016ffd5f
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs
new file mode 100644
index 0000000..24016ca
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs
@@ -0,0 +1,23 @@
+using System;
+using UnityEngine;
+
+namespace UnityEditor.Timeline
+{
+ struct StyleNormalColorOverride : IDisposable
+ {
+ readonly GUIStyle m_Style;
+ readonly Color m_OldColor;
+
+ public StyleNormalColorOverride(GUIStyle style, Color newColor)
+ {
+ m_Style = style;
+ m_OldColor = style.normal.textColor;
+ style.normal.textColor = newColor;
+ }
+
+ public void Dispose()
+ {
+ m_Style.normal.textColor = m_OldColor;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs.meta
new file mode 100644
index 0000000..b969311
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/StyleNormalColorOverride.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2bd3ca1fde4b154448ef972b0f9d292e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs
new file mode 100644
index 0000000..4e456f8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs
@@ -0,0 +1,57 @@
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ static class TimeReferenceUtility
+ {
+ static WindowState state { get { return TimelineWindow.instance.state; } }
+
+ public static double SnapToFrame(double time)
+ {
+ if (state.timeReferenceMode == TimeReferenceMode.Global)
+ {
+ time = state.editSequence.ToGlobalTime(time);
+ time = TimeUtility.RoundToFrame(time, state.referenceSequence.frameRate);
+ return state.editSequence.ToLocalTime(time);
+ }
+
+ return TimeUtility.RoundToFrame(time, state.referenceSequence.frameRate);
+ }
+
+ public static string ToTimeString(double time, string format = "F2")
+ {
+ if (state.timeReferenceMode == TimeReferenceMode.Global)
+ time = state.editSequence.ToGlobalTime(time);
+
+ return state.editSequence.viewModel.timeInFrames ?
+ TimeUtility.TimeAsFrames(time, state.referenceSequence.frameRate, format) :
+ TimeUtility.TimeAsTimeCode(time, state.referenceSequence.frameRate, format);
+ }
+
+ public static double FromTimeString(string timeString)
+ {
+ double newTime;
+
+ if (state.timeInFrames)
+ {
+ double newFrameDouble;
+ if (double.TryParse(timeString, out newFrameDouble))
+ newTime = TimeUtility.FromFrames(newFrameDouble, state.referenceSequence.frameRate);
+ else
+ newTime = state.editSequence.time;
+ }
+ else
+ {
+ newTime = TimeUtility.ParseTimeCode(timeString, state.referenceSequence.frameRate, -1);
+ }
+
+ if (newTime >= 0.0)
+ {
+ return state.timeReferenceMode == TimeReferenceMode.Global ?
+ state.editSequence.ToLocalTime(newTime) : newTime;
+ }
+
+ return state.editSequence.time;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs.meta
new file mode 100644
index 0000000..1da1a4a
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimeReferenceUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f6bb32665bcc91b41a7177fd6af08ad6
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs
new file mode 100644
index 0000000..3cd18d8
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs
@@ -0,0 +1,387 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEditor.IMGUI.Controls;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ static class KeyboardNavigation
+ {
+ public static void FrameTrackHeader(TreeViewItem treeItem = null)
+ {
+ if (TrackHeadActive())
+ treeItem = treeItem ?? SelectionManager.SelectedTrackGUI().Last();
+ else
+ {
+ var item = GetVisibleSelectedItems().LastOrDefault();
+ treeItem = TimelineWindow.instance.allTracks.FirstOrDefault(
+ x => item != null && x.track == item.parentTrack);
+ }
+
+ if (treeItem != null)
+ TimelineWindow.instance.treeView.FrameItem(treeItem);
+ }
+
+ public static bool TrackHeadActive()
+ {
+ return SelectionManager.SelectedTracks().Any(x => x.IsVisibleRecursive()) && !ClipAreaActive();
+ }
+
+ public static bool ClipAreaActive()
+ {
+ return GetVisibleSelectedItems().Any();
+ }
+
+ public static IEnumerable<ITimelineItem> GetVisibleSelectedItems()
+ {
+ return SelectionManager.SelectedItems().Where(x => x.parentTrack.IsVisibleRecursive());
+ }
+
+ public static IEnumerable<TimelineTrackBaseGUI> GetVisibleTracks()
+ {
+ return TimelineWindow.instance.allTracks.Where(x => x.track.IsVisibleRecursive());
+ }
+
+ static TrackAsset PreviousTrack(this TrackAsset track)
+ {
+ var uiOrderTracks = GetVisibleTracks().Select(t => t.track).ToList();
+ var selIdx = uiOrderTracks.IndexOf(track);
+ return selIdx > 0 ? uiOrderTracks[selIdx - 1] : null;
+ }
+
+ static TrackAsset NextTrack(this TrackAsset track)
+ {
+ var uiOrderTracks = GetVisibleTracks().Select(t => t.track).ToList();
+ var selIdx = uiOrderTracks.IndexOf(track);
+ return selIdx < uiOrderTracks.Count - 1 && selIdx != -1 ? uiOrderTracks[selIdx + 1] : null;
+ }
+
+ static ITimelineItem PreviousItem(this ITimelineItem item, bool clipOnly)
+ {
+ var items = item.parentTrack.GetItems().ToArray();
+ if (clipOnly)
+ {
+ items = items.Where(x => x is ClipItem).ToArray();
+ }
+ else
+ {
+ items = items.Where(x => x is MarkerItem).ToArray();
+ }
+
+ var idx = Array.IndexOf(items, item);
+ return idx > 0 ? items[idx - 1] : null;
+ }
+
+ static ITimelineItem NextItem(this ITimelineItem item, bool clipOnly)
+ {
+ var items = item.parentTrack.GetItems().ToArray();
+ if (clipOnly)
+ {
+ items = items.Where(x => x is ClipItem).ToArray();
+ }
+ else
+ {
+ items = items.Where(x => x is MarkerItem).ToArray();
+ }
+
+ var idx = Array.IndexOf(items, item);
+ return idx < items.Length - 1 ? items[idx + 1] : null;
+ }
+
+ static bool FilterItems(ref List<ITimelineItem> items)
+ {
+ var clipOnly = false;
+ if (items.Any(x => x is ClipItem))
+ {
+ items = items.Where(x => x is ClipItem).ToList();
+ clipOnly = true;
+ }
+
+ return clipOnly;
+ }
+
+ static ITimelineItem GetClosestItem(TrackAsset track, ITimelineItem refItem)
+ {
+ var start = refItem.start;
+ var end = refItem.end;
+ var items = track.GetItems().ToList();
+
+ if (refItem is ClipItem)
+ {
+ items = items.Where(x => x is ClipItem).ToList();
+ }
+ else
+ {
+ items = items.Where(x => x is MarkerItem).ToList();
+ }
+
+ if (!items.Any())
+ return null;
+ ITimelineItem ret = null;
+ var scoreToBeat = double.NegativeInfinity;
+
+ foreach (var item in items)
+ {
+ // test for overlap
+ var low = Math.Max(item.start, start);
+ var high = Math.Min(item.end, end);
+ if (low <= high)
+ {
+ var score = high - low;
+ if (score >= scoreToBeat)
+ {
+ scoreToBeat = score;
+ ret = item;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+ public static bool FocusFirstVisibleItem(WindowState state,
+ IEnumerable<TrackAsset> focusTracks = null)
+ {
+ var timeRange = state.timeAreaShownRange;
+
+ var tracks = focusTracks ?? TimelineWindow.instance.treeView.visibleTracks.Where(x => x.IsVisibleRecursive() && x.GetItems().Any());
+ var items = tracks.SelectMany(t => t.GetItems().OfType<ClipItem>().Where(x => x.end >= timeRange.x && x.end <= timeRange.y ||
+ x.start >= timeRange.x && x.start <= timeRange.y)).ToList();
+ var itemFullyInView = items.Where(x => x.end >= timeRange.x && x.end <= timeRange.y &&
+ x.start >= timeRange.x && x.start <= timeRange.y);
+ var itemToSelect = itemFullyInView.FirstOrDefault() ?? items.FirstOrDefault();
+ if (itemToSelect != null)
+ {
+ SelectionManager.SelectOnly(itemToSelect);
+ return true;
+ }
+ return false;
+ }
+
+ public static bool CollapseGroup(WindowState state)
+ {
+ if (TrackHeadActive())
+ {
+ var quit = false;
+ foreach (var track in SelectionManager.SelectedTracks())
+ {
+ if (!track.GetChildTracks().Any())
+ continue;
+ if (!quit && !track.GetCollapsed())
+ quit = true;
+ track.SetCollapsed(true);
+ }
+ if (quit)
+ {
+ state.Refresh();
+ return true;
+ }
+
+ var selectedTrack = SelectionManager.SelectedTracks().LastOrDefault();
+ var parent = selectedTrack != null ? selectedTrack.parent as TrackAsset : null;
+ if (parent)
+ {
+ SelectionManager.SelectOnly(parent);
+ FrameTrackHeader(GetVisibleTracks().First(x => x.track == parent));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static bool SelectLeftItem(WindowState state, bool shift = false)
+ {
+ if (ClipAreaActive())
+ {
+ var items = SelectionManager.SelectedItems().ToList();
+ var clipOnly = FilterItems(ref items);
+
+ var item = items.Last();
+ var prev = item.PreviousItem(clipOnly);
+ if (prev != null)
+ {
+ if (shift)
+ {
+ if (SelectionManager.Contains(prev))
+ SelectionManager.Remove(item);
+ SelectionManager.Add(prev);
+ }
+ else
+ SelectionManager.SelectOnly(prev);
+ TimelineHelpers.FrameItems(state, new[] {prev});
+ }
+ else if (item != null && !shift && item.parentTrack != state.editSequence.asset.markerTrack)
+ SelectionManager.SelectOnly(item.parentTrack);
+ return true;
+ }
+ return false;
+ }
+
+ public static bool SelectRightItem(WindowState state, bool shift = false)
+ {
+ if (ClipAreaActive())
+ {
+ var items = SelectionManager.SelectedItems().ToList();
+ var clipOnly = FilterItems(ref items);
+
+ var item = items.Last();
+ var next = item.NextItem(clipOnly);
+ if (next != null)
+ {
+ if (shift)
+ {
+ if (SelectionManager.Contains(next))
+ SelectionManager.Remove(item);
+ SelectionManager.Add(next);
+ }
+ else
+ SelectionManager.SelectOnly(next);
+ TimelineHelpers.FrameItems(state, new[] {next});
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static bool UnCollapseGroup(WindowState state)
+ {
+ if (TrackHeadActive())
+ {
+ var quit = false;
+ foreach (var track in SelectionManager.SelectedTracks())
+ {
+ if (!track.GetChildTracks().Any()) continue;
+
+ if (!quit && track.GetCollapsed())
+ quit = true;
+ track.SetCollapsed(false);
+ }
+
+ if (quit)
+ {
+ state.Refresh();
+ return true;
+ }
+
+ // Transition to Clip area
+ var visibleTracks = GetVisibleTracks().Select(x => x.track).ToList();
+ var idx = visibleTracks.IndexOf(SelectionManager.SelectedTracks().Last());
+ ITimelineItem item = null;
+ for (var i = idx; i < visibleTracks.Count; ++i)
+ {
+ var items = visibleTracks[i].GetItems().OfType<ClipItem>();
+ if (!items.Any())
+ continue;
+ item = items.First();
+ break;
+ }
+
+ if (item != null)
+ {
+ SelectionManager.SelectOnly(item);
+ TimelineHelpers.FrameItems(state, new[] {item});
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static bool SelectUpTrack(bool shift = false)
+ {
+ if (TrackHeadActive())
+ {
+ var prevTrack = PreviousTrack(SelectionManager.SelectedTracks().Last());
+ if (prevTrack != null)
+ {
+ if (shift)
+ {
+ if (SelectionManager.Contains(prevTrack))
+ SelectionManager.Remove(SelectionManager.SelectedTracks().Last());
+ SelectionManager.Add(prevTrack);
+ }
+ else
+ SelectionManager.SelectOnly(prevTrack);
+ FrameTrackHeader(GetVisibleTracks().First(x => x.track == prevTrack));
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public static bool SelectUpItem(WindowState state)
+ {
+ if (ClipAreaActive())
+ {
+ var refItem = SelectionManager.SelectedItems().Last();
+ var prevTrack = refItem.parentTrack.PreviousTrack();
+ while (prevTrack != null)
+ {
+ var selectionItem = GetClosestItem(prevTrack, refItem);
+ if (selectionItem == null)
+ {
+ prevTrack = prevTrack.PreviousTrack();
+ continue;
+ }
+
+ SelectionManager.SelectOnly(selectionItem);
+ TimelineHelpers.FrameItems(state, new[] {selectionItem});
+ FrameTrackHeader(GetVisibleTracks().First(x => x.track == selectionItem.parentTrack));
+ break;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool SelectDownTrack(bool shift = false)
+ {
+ if (TrackHeadActive())
+ {
+ var nextTrack = SelectionManager.SelectedTracks().Last().NextTrack();
+ if (nextTrack != null)
+ {
+ if (shift)
+ {
+ if (SelectionManager.Contains(nextTrack))
+ SelectionManager.Remove(SelectionManager.SelectedTracks().Last());
+ SelectionManager.Add(nextTrack);
+ }
+ else
+ SelectionManager.SelectOnly(nextTrack);
+
+ FrameTrackHeader(GetVisibleTracks().First(x => x.track == nextTrack));
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool SelectDownItem(WindowState state)
+ {
+ if (ClipAreaActive())
+ {
+ var refItem = SelectionManager.SelectedItems().Last();
+ var nextTrack = refItem.parentTrack.NextTrack();
+ while (nextTrack != null)
+ {
+ var selectionItem = GetClosestItem(nextTrack, refItem);
+ if (selectionItem == null)
+ {
+ nextTrack = nextTrack.NextTrack();
+ continue;
+ }
+
+ SelectionManager.SelectOnly(selectionItem);
+ TimelineHelpers.FrameItems(state, new[] {selectionItem});
+ FrameTrackHeader(GetVisibleTracks().First(x => x.track == selectionItem.parentTrack));
+ break;
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs.meta
new file mode 100644
index 0000000..7fb6aea
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TimelineKeyboardNavigation.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9be6112c2b1c3ae44927680ba7b36e10
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs
new file mode 100644
index 0000000..5afeb52
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs
@@ -0,0 +1,21 @@
+using UnityEngine;
+using UnityEditor;
+using UnityEngine.Timeline;
+using UnityEngine.Playables;
+
+namespace UnityEditor.Timeline
+{
+ static class TrackModifier
+ {
+ public static bool DeleteTrack(TimelineAsset timeline, TrackAsset track)
+ {
+ if (TimelineEditor.inspectedDirector != null)
+ {
+ TimelineUndo.PushUndo(TimelineEditor.inspectedDirector, "Delete Track");
+ TimelineEditor.inspectedDirector.ClearGenericBinding(track);
+ }
+
+ return timeline.DeleteTrack(track);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs.meta
new file mode 100644
index 0000000..f221e10
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackModifier.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 411b7c7ffc0960249b35a2a247b66ff7
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs
new file mode 100644
index 0000000..8eda6fe
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.Timeline;
+
+namespace UnityEditor.Timeline
+{
+ static class TrackResourceCache
+ {
+ private static Dictionary<System.Type, GUIContent> s_TrackIconCache = new Dictionary<Type, GUIContent>(10);
+ private static Dictionary<System.Type, Color> s_TrackColorCache = new Dictionary<Type, Color>(10);
+ public static GUIContent s_DefaultIcon = EditorGUIUtility.IconContent("UnityEngine/ScriptableObject Icon");
+
+ public static GUIContent GetTrackIcon(TrackAsset track)
+ {
+ if (track == null)
+ return s_DefaultIcon;
+
+ GUIContent content = null;
+ if (!s_TrackIconCache.TryGetValue(track.GetType(), out content))
+ {
+ content = FindTrackIcon(track);
+ s_TrackIconCache[track.GetType()] = content;
+ }
+ return content;
+ }
+
+ public static Color GetTrackColor(TrackAsset track)
+ {
+ if (track == null)
+ return Color.white;
+
+ // Try to ensure DirectorStyles is initialized first
+ // Note: GUISkin.current must exist to be able do so
+ if (!DirectorStyles.IsInitialized && GUISkin.current != null)
+ DirectorStyles.ReloadStylesIfNeeded();
+
+ Color color;
+ if (!s_TrackColorCache.TryGetValue(track.GetType(), out color))
+ {
+ var attr = track.GetType().GetCustomAttributes(typeof(TrackColorAttribute), true);
+ if (attr.Length > 0)
+ {
+ color = ((TrackColorAttribute)attr[0]).color;
+ }
+ else
+ {
+ // case 1141958
+ // There was an error initializing DirectorStyles
+ if (!DirectorStyles.IsInitialized)
+ return Color.white;
+
+ color = DirectorStyles.Instance.customSkin.colorDefaultTrackDrawer;
+ }
+
+ s_TrackColorCache[track.GetType()] = color;
+ }
+ return color;
+ }
+
+ public static void ClearTrackIconCache()
+ {
+ s_TrackIconCache.Clear();
+ }
+
+ public static void SetTrackIcon<T>(GUIContent content) where T : TrackAsset
+ {
+ s_TrackIconCache[typeof(T)] = content;
+ }
+
+ public static void ClearTrackColorCache()
+ {
+ s_TrackColorCache.Clear();
+ }
+
+ public static void SetTrackColor<T>(Color c) where T : TrackAsset
+ {
+ s_TrackColorCache[typeof(T)] = c;
+ }
+
+ private static GUIContent FindTrackIcon(TrackAsset track)
+ {
+ // backwards compatible -- try to load from Gizmos folder
+ Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/Gizmos/" + track.GetType().Name + ".png");
+ if (texture != null)
+ return new GUIContent(texture);
+
+ // try to load based on the binding type
+ var binding = track.outputs.FirstOrDefault();
+ if (binding.outputTargetType != null)
+ {
+ // Type calls don't properly handle monobehaviours, because an instance is required to
+ // get the monoscript icons
+ if (typeof(MonoBehaviour).IsAssignableFrom(binding.outputTargetType))
+ {
+ texture = null;
+ var scripts = UnityEngine.Resources.FindObjectsOfTypeAll<MonoScript>();
+ foreach (var script in scripts)
+ {
+ if (script.GetClass() == binding.outputTargetType)
+ {
+ texture = AssetPreview.GetMiniThumbnail(script);
+ break;
+ }
+ }
+ }
+ else
+ {
+ texture = EditorGUIUtility.FindTexture(binding.outputTargetType);
+ }
+
+ if (texture != null)
+ return new GUIContent(texture);
+ }
+
+ // default to the scriptable object icon
+ return s_DefaultIcon;
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs.meta
new file mode 100644
index 0000000..be2a519
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TrackResourceCache.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 63f2caa33e79582448112b2e286d576d
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs
new file mode 100644
index 0000000..2c28266
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs
@@ -0,0 +1,342 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using UnityEngine;
+using UnityEngine.Playables;
+using UnityEngine.Timeline;
+using Component = UnityEngine.Component;
+using Object = UnityEngine.Object;
+
+namespace UnityEditor.Timeline
+{
+ static class TypeUtility
+ {
+ private static Type[] s_AllTrackTypes;
+ private static Type[] s_AllClipTypes;
+ private static Type[] s_MarkerTypes;
+ private static Dictionary<Type, Type[]> s_TrackTypeToVisibleClipType = new Dictionary<Type, Type[]>();
+ private static Dictionary<Type, Type[]> s_TrackTypeToAllClipType = new Dictionary<Type, Type[]>();
+ private static Dictionary<Type, TrackBindingTypeAttribute> s_TrackToBindingCache = new Dictionary<Type, TrackBindingTypeAttribute>();
+
+ public static bool IsConcretePlayableAsset(Type t)
+ {
+ return typeof(IPlayableAsset).IsAssignableFrom(t)
+ && IsConcreteAsset(t);
+ }
+
+ private static bool IsConcreteAsset(Type t)
+ {
+ return typeof(ScriptableObject).IsAssignableFrom(t)
+ && !t.IsAbstract
+ && !t.IsGenericType
+ && !t.IsInterface
+ && !typeof(TrackAsset).IsAssignableFrom(t)
+ && !typeof(TimelineAsset).IsAssignableFrom(t);
+ }
+
+ /// <summary>
+ /// List of all PlayableAssets
+ /// </summary>
+ public static IEnumerable<Type> AllClipTypes()
+ {
+ if (s_AllClipTypes == null)
+ {
+ s_AllClipTypes = TypeCache.GetTypesDerivedFrom<IPlayableAsset>().
+ Where(t => IsConcreteAsset(t)).
+ ToArray();
+ }
+ return s_AllClipTypes;
+ }
+
+ public static IEnumerable<Type> AllTrackTypes()
+ {
+ if (s_AllTrackTypes == null)
+ {
+ s_AllTrackTypes = TypeCache.GetTypesDerivedFrom<TrackAsset>()
+ .Where(x => !x.IsAbstract)
+ .ToArray();
+ }
+
+ return s_AllTrackTypes;
+ }
+
+ public static IEnumerable<Type> GetVisiblePlayableAssetsHandledByTrack(Type trackType)
+ {
+ if (trackType == null || !typeof(TrackAsset).IsAssignableFrom(trackType))
+ return Enumerable.Empty<Type>();
+
+ Type[] types;
+ if (s_TrackTypeToVisibleClipType.TryGetValue(trackType, out types))
+ {
+ return types;
+ }
+
+ // special case -- the playable track handles all types not handled by other tracks
+ if (trackType == typeof(PlayableTrack))
+ {
+ types = GetUnhandledClipTypes().ToArray();
+ s_TrackTypeToVisibleClipType[trackType] = types;
+ return types;
+ }
+
+ var attributes = trackType.GetCustomAttributes(typeof(TrackClipTypeAttribute), true);
+ var baseClasses = attributes.
+ OfType<TrackClipTypeAttribute>().
+ Where(t => t.allowAutoCreate).
+ Select(a => a.inspectedType);
+
+ types = AllClipTypes().Where(t => baseClasses.Any(x => x.IsAssignableFrom(t))).ToArray();
+ s_TrackTypeToVisibleClipType[trackType] = types;
+ return types;
+ }
+
+ public static IEnumerable<Type> GetPlayableAssetsHandledByTrack(Type trackType)
+ {
+ if (trackType == null || !typeof(TrackAsset).IsAssignableFrom(trackType))
+ return Enumerable.Empty<Type>();
+
+ Type[] types;
+ if (s_TrackTypeToAllClipType.TryGetValue(trackType, out types))
+ {
+ return types;
+ }
+
+ // special case -- the playable track handles all types not handled by other tracks
+ if (trackType == typeof(PlayableTrack))
+ {
+ types = GetUnhandledClipTypes().ToArray();
+ s_TrackTypeToAllClipType[trackType] = types;
+ return types;
+ }
+
+ var attributes = trackType.GetCustomAttributes(typeof(TrackClipTypeAttribute), true);
+ var baseClasses = attributes.
+ OfType<TrackClipTypeAttribute>().
+ Select(a => a.inspectedType);
+
+ types = AllClipTypes().Where(t => baseClasses.Any(x => x.IsAssignableFrom(t))).ToArray();
+ s_TrackTypeToAllClipType[trackType] = types;
+ return types;
+ }
+
+ /// <summary>
+ /// Returns the binding attribute attrached to the track
+ /// </summary>
+ public static TrackBindingTypeAttribute GetTrackBindingAttribute(Type trackType)
+ {
+ if (trackType == null || !typeof(TrackAsset).IsAssignableFrom(trackType))
+ return null;
+
+ TrackBindingTypeAttribute attribute = null;
+ if (!s_TrackToBindingCache.TryGetValue(trackType, out attribute))
+ {
+ attribute = (TrackBindingTypeAttribute)Attribute.GetCustomAttribute(trackType, typeof(TrackBindingTypeAttribute));
+ s_TrackToBindingCache.Add(trackType, attribute);
+ }
+
+ return attribute;
+ }
+
+ /// <summary>
+ /// True if the given track has a clip type that handles the given object
+ /// </summary>
+ public static bool TrackHasClipForObject(Type trackType, Object obj)
+ {
+ return GetPlayableAssetsHandledByTrack(trackType)
+ .Any(c => ObjectReferenceField.FindObjectReferences(c).Any(o => o.IsAssignable(obj)));
+ }
+
+ /// <summary>
+ /// Get the list of markers that have fields for the object
+ /// </summary>
+ public static IEnumerable<Type> MarkerTypesWithFieldForObject(Object obj)
+ {
+ return GetAllMarkerTypes().Where(
+ c => ObjectReferenceField.FindObjectReferences(c).Any(o => o.IsAssignable(obj))
+ );
+ }
+
+ /// <summary>
+ /// Get the list of tracks that can handle this object as clips
+ /// </summary>
+ public static IEnumerable<Type> GetTrackTypesForObject(Object obj)
+ {
+ if (obj == null)
+ return Enumerable.Empty<Type>();
+
+ return AllTrackTypes().Where(t => TrackHasClipForObject(t, obj));
+ }
+
+ /// <summary>
+ /// Given a trackType and an object, does the binding type match
+ /// Takes into account whether creating a missing component is permitted
+ /// </summary>
+ public static bool IsTrackCreatableFromObject(Object obj, Type trackType)
+ {
+ if (obj == null || obj.IsPrefab())
+ return false;
+
+ var attribute = GetTrackBindingAttribute(trackType);
+ if (attribute == null || attribute.type == null)
+ return false;
+
+ if (attribute.type.IsAssignableFrom(obj.GetType()))
+ return true;
+
+ var gameObject = obj as GameObject;
+ if (gameObject != null && typeof(Component).IsAssignableFrom(attribute.type))
+ {
+ return gameObject.GetComponent(attribute.type) != null ||
+ (attribute.flags & TrackBindingFlags.AllowCreateComponent) != 0;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Given an object, get the list of track that are creatable from it. Takes
+ /// binding flags into account
+ /// </summary>
+ public static IEnumerable<Type> GetTracksCreatableFromObject(Object obj)
+ {
+ if (obj == null)
+ return Enumerable.Empty<Type>();
+
+ return AllTrackTypes().Where(t => !IsHiddenInMenu(t) && IsTrackCreatableFromObject(obj, t));
+ }
+
+ /// <summary>
+ /// Get the list of playable assets that can handle an object for a particular track
+ /// </summary>
+ /// <param name="trackType">The type of the track</param>
+ /// <param name="obj">The object to handle</param>
+ /// <returns></returns>
+ public static IEnumerable<Type> GetAssetTypesForObject(Type trackType, Object obj)
+ {
+ if (obj == null)
+ return Enumerable.Empty<Type>();
+
+ return GetPlayableAssetsHandledByTrack(trackType).Where(
+ c => ObjectReferenceField.FindObjectReferences(c).Any(o => o.IsAssignable(obj))
+ );
+ }
+
+ // get the track types for a track from it's attributes
+ private static IEnumerable<Type> GetTrackClipTypesFromAttributes(Type trackType)
+ {
+ if (trackType == null || !typeof(TrackAsset).IsAssignableFrom(trackType))
+ return Enumerable.Empty<Type>();
+
+ var attributes = trackType.GetCustomAttributes(typeof(TrackClipTypeAttribute), true);
+ var baseClasses = attributes.
+ OfType<TrackClipTypeAttribute>().
+ Select(a => a.inspectedType);
+
+ return AllClipTypes().Where(t => baseClasses.Any(x => x.IsAssignableFrom(t)));
+ }
+
+ // find the playable asset types that are unhandled
+ private static IEnumerable<Type> GetUnhandledClipTypes()
+ {
+ var typesHandledByTrack = AllTrackTypes().SelectMany(t => GetTrackClipTypesFromAttributes(t));
+
+ // exclude anything in the timeline assembly, handled by tracks, has a hide in menu attribute
+ // or is explicity ignored
+ return AllClipTypes()
+ .Except(typesHandledByTrack)
+ .Where(t => !TypeUtility.IsBuiltIn(t)) // exclude built-in
+ .Where(t => !typeof(TrackAsset).IsAssignableFrom(t)) // exclude track types (they are playable assets)
+ .Where(t => !t.IsDefined(typeof(HideInMenuAttribute), false) && !t.IsDefined(typeof(IgnoreOnPlayableTrackAttribute), true))
+ .Distinct();
+ }
+
+ public static IEnumerable<Type> GetAllMarkerTypes()
+ {
+ if (s_MarkerTypes == null)
+ {
+ s_MarkerTypes = TypeCache.GetTypesDerivedFrom<IMarker>()
+ .Where(x =>
+ typeof(ScriptableObject).IsAssignableFrom(x)
+ && !x.IsAbstract
+ && !x.IsGenericType
+ && !x.IsInterface)
+ .ToArray();
+ }
+ return s_MarkerTypes;
+ }
+
+ public static IEnumerable<Type> GetUserMarkerTypes()
+ {
+ return GetAllMarkerTypes().Where(x => !IsBuiltIn(x) && !IsHiddenInMenu(x));
+ }
+
+ public static IEnumerable<Type> GetBuiltInMarkerTypes()
+ {
+ return GetAllMarkerTypes().Where(TypeUtility.IsBuiltIn);
+ }
+
+ public static bool DoesTrackSupportMarkerType(TrackAsset track, Type type)
+ {
+ if (track.supportsNotifications)
+ {
+ return true;
+ }
+
+ return !typeof(INotification).IsAssignableFrom(type);
+ }
+
+ internal static string GetDisplayName(Type t)
+ {
+ var displayName = ObjectNames.NicifyVariableName(t.Name);
+ var attr = Attribute.GetCustomAttribute(t, typeof(DisplayNameAttribute)) as DisplayNameAttribute;
+ if (attr != null)
+ displayName = attr.DisplayName;
+ return displayName;
+ }
+
+ public static bool IsHiddenInMenu(Type type)
+ {
+ var attr = type.GetCustomAttributes(typeof(HideInMenuAttribute), false);
+ return attr.Length > 0;
+ }
+
+ public struct ObjectReference
+ {
+ public Type type;
+ public bool isSceneReference;
+ }
+
+ public static IEnumerable<ObjectReference> ObjectReferencesForType(Type type)
+ {
+ var objectReferences = ObjectReferenceField.FindObjectReferences(type);
+ var uniqueTypes = objectReferences.Select(objRef => objRef.type).Distinct();
+ foreach (var refType in uniqueTypes)
+ {
+ var isSceneReference = objectReferences.Any(objRef => objRef.type == refType && objRef.isSceneReference);
+ yield return new ObjectReference { type = refType, isSceneReference = isSceneReference };
+ }
+ }
+
+ /// <summary>
+ /// Checks whether a type has an overridden method with a specific name. This method also checks overridden members in parent classes.
+ /// </summary>
+ public static bool HasOverrideMethod(System.Type t, string name)
+ {
+ const MethodAttributes mask = MethodAttributes.Virtual | MethodAttributes.NewSlot;
+ const MethodAttributes expectedResult = MethodAttributes.Virtual;
+
+ var method = t.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ return method != null && (method.Attributes & mask) == expectedResult;
+ }
+
+ /// <summary>
+ /// Returns whether the given type resides in the timeline assembly
+ /// </summary>
+ public static bool IsBuiltIn(System.Type t)
+ {
+ return t != null && t.Assembly.Equals(typeof(TimelineAsset).Assembly);
+ }
+ }
+}
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs.meta
new file mode 100644
index 0000000..e73d461
--- /dev/null
+++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/TypeUtility.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4c1821c1816c6fa44967b8ecb79ea7e4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: