From c55fba8ab2a1c9d3df65eda4a5a1e957f4aa1f78 Mon Sep 17 00:00:00 2001 From: Andrew Lee Date: Sun, 19 Apr 2020 17:19:32 -0400 Subject: Inital commit --- .../inspectors/ClipInspector/ClipInspector.cs | 786 +++++++++++++++++++++ .../inspectors/ClipInspector/ClipInspector.cs.meta | 11 + .../ClipInspector/ClipInspectorCurveEditor.cs | 348 +++++++++ .../ClipInspector/ClipInspectorCurveEditor.cs.meta | 11 + .../ClipInspector/ClipInspectorSelectionInfo.cs | 132 ++++ .../ClipInspectorSelectionInfo.cs.meta | 11 + 6 files changed, 1299 insertions(+) create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs.meta create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs.meta create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs create mode 100644 Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs.meta (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector') diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs new file mode 100644 index 0000000..f05cb29 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs @@ -0,0 +1,786 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditorInternal; +using UnityEngine; +using UnityEngine.Timeline; +using UnityObject = UnityEngine.Object; + +namespace UnityEditor.Timeline +{ + [CustomEditor(typeof(EditorClip)), CanEditMultipleObjects] + class ClipInspector : Editor + { + internal static class Styles + { + public static readonly GUIContent StartName = EditorGUIUtility.TrTextContent("Start", "The start time of the clip"); + public static readonly GUIContent DurationName = EditorGUIUtility.TrTextContent("Duration", "The length of the clip"); + public static readonly GUIContent EndName = EditorGUIUtility.TrTextContent("End", "The end time of the clip"); + public static readonly GUIContent EaseInDurationName = EditorGUIUtility.TrTextContent("Ease In Duration", "The length of the blend in"); + public static readonly GUIContent EaseOutDurationName = EditorGUIUtility.TrTextContent("Ease Out Duration", "The length of the blend out"); + public static readonly GUIContent ClipInName = EditorGUIUtility.TrTextContent("Clip In", "Start the clip at this local time"); + public static readonly GUIContent TimeScaleName = EditorGUIUtility.TrTextContent("Speed Multiplier", "Time scale of the playback speed"); + public static readonly GUIContent PreExtrapolateLabel = EditorGUIUtility.TrTextContent("Pre-Extrapolate", "Extrapolation used prior to the first clip"); + public static readonly GUIContent PostExtrapolateLabel = EditorGUIUtility.TrTextContent("Post-Extrapolate", "Extrapolation used after a clip ends"); + public static readonly GUIContent BlendInCurveName = EditorGUIUtility.TrTextContent("In", "Blend In Curve"); + public static readonly GUIContent BlendOutCurveName = EditorGUIUtility.TrTextContent("Out", "Blend Out Curve"); + public static readonly GUIContent PreviewTitle = EditorGUIUtility.TrTextContent("Curve Editor"); + public static readonly GUIContent ClipTimingTitle = EditorGUIUtility.TrTextContent("Clip Timing"); + public static readonly GUIContent AnimationExtrapolationTitle = EditorGUIUtility.TrTextContent("Animation Extrapolation"); + public static readonly GUIContent BlendCurvesTitle = EditorGUIUtility.TrTextContent("Blend Curves"); + public static readonly GUIContent GroupTimingTitle = EditorGUIUtility.TrTextContent("Multiple Clip Timing"); + public static readonly GUIContent MultipleClipsSelectedIncompatibleCapabilitiesWarning = EditorGUIUtility.TrTextContent("Multiple clips selected. Only common properties are shown."); + public static readonly GUIContent MultipleSelectionTitle = EditorGUIUtility.TrTextContent("Timeline Clips"); + public static readonly GUIContent MultipleClipStartName = EditorGUIUtility.TrTextContent("Start", "The start time of the clip group"); + public static readonly GUIContent MultipleClipEndName = EditorGUIUtility.TrTextContent("End", "The end time of the clip group"); + public static readonly GUIContent TimelineClipFG = DirectorStyles.IconContent("TimelineClipFG"); + public static readonly GUIContent TimelineClipBG = DirectorStyles.IconContent("TimelineClipBG"); + } + + class EditorClipSelection : ICurvesOwnerInspectorWrapper + { + public EditorClip editorClip { get; } + + public TimelineClip clip + { + get { return editorClip == null ? null : editorClip.clip; } + } + + public SerializedObject serializedPlayableAsset { get; } + + public ICurvesOwner curvesOwner + { + get { return clip; } + } + + public int lastCurveVersion { get; set; } + public double lastEvalTime { get; set; } + + public EditorClipSelection(EditorClip anEditorClip) + { + editorClip = anEditorClip; + lastCurveVersion = -1; + lastEvalTime = -1; + + var so = new SerializedObject(editorClip); + var playableAssetProperty = so.FindProperty("m_Clip.m_Asset"); + if (playableAssetProperty != null) + { + var asset = playableAssetProperty.objectReferenceValue as UnityEngine.Playables.PlayableAsset; + if (asset != null) + serializedPlayableAsset = new SerializedObject(asset); + } + } + + public double ToLocalTime(double time) + { + return clip == null ? time : clip.ToLocalTime(time); + } + } + + SerializedProperty m_DisplayNameProperty; + SerializedProperty m_BlendInDurationProperty; + SerializedProperty m_BlendOutDurationProperty; + SerializedProperty m_EaseInDurationProperty; + SerializedProperty m_EaseOutDurationProperty; + SerializedProperty m_ClipInProperty; + SerializedProperty m_TimeScaleProperty; + SerializedProperty m_PostExtrapolationModeProperty; + SerializedProperty m_PreExtrapolationModeProperty; + SerializedProperty m_PostExtrapolationTimeProperty; + SerializedProperty m_PreExtrapolationTimeProperty; + SerializedProperty m_MixInCurveProperty; + SerializedProperty m_MixOutCurveProperty; + SerializedProperty m_BlendInCurveModeProperty; + SerializedProperty m_BlendOutCurveModeProperty; + + void InitializeProperties() + { + m_DisplayNameProperty = serializedObject.FindProperty("m_Clip.m_DisplayName"); + m_BlendInDurationProperty = serializedObject.FindProperty("m_Clip.m_BlendInDuration"); + m_BlendOutDurationProperty = serializedObject.FindProperty("m_Clip.m_BlendOutDuration"); + m_EaseInDurationProperty = serializedObject.FindProperty("m_Clip.m_EaseInDuration"); + m_EaseOutDurationProperty = serializedObject.FindProperty("m_Clip.m_EaseOutDuration"); + m_ClipInProperty = serializedObject.FindProperty("m_Clip.m_ClipIn"); + m_TimeScaleProperty = serializedObject.FindProperty("m_Clip.m_TimeScale"); + m_PostExtrapolationModeProperty = serializedObject.FindProperty("m_Clip.m_PostExtrapolationMode"); + m_PreExtrapolationModeProperty = serializedObject.FindProperty("m_Clip.m_PreExtrapolationMode"); + m_PostExtrapolationTimeProperty = serializedObject.FindProperty("m_Clip.m_PostExtrapolationTime"); + m_PreExtrapolationTimeProperty = serializedObject.FindProperty("m_Clip.m_PreExtrapolationTime"); + m_MixInCurveProperty = serializedObject.FindProperty("m_Clip.m_MixInCurve"); + m_MixOutCurveProperty = serializedObject.FindProperty("m_Clip.m_MixOutCurve"); + m_BlendInCurveModeProperty = serializedObject.FindProperty("m_Clip.m_BlendInCurveMode"); + m_BlendOutCurveModeProperty = serializedObject.FindProperty("m_Clip.m_BlendOutCurveMode"); + } + + TimelineAsset m_TimelineAsset; + + List m_SelectionCache; + Editor m_SelectedPlayableAssetsInspector; + + ClipInspectorCurveEditor m_ClipCurveEditor; + AnimationCurve[] m_PreviewCurves; // the curves we are currently previewing. + CurvePresetLibrary m_CurvePresets; + + bool m_IsClipAssetInspectorExpanded = true; + GUIContent m_ClipAssetTitle = new GUIContent(); + string m_MultiselectionHeaderTitle; + + ClipInspectorSelectionInfo m_SelectionInfo; + + const double k_TimeScaleSensitivity = 0.003; + + bool hasMultipleSelection + { + get { return targets.Length > 1; } + } + + float currentFrameRate + { + get { return m_TimelineAsset != null ? m_TimelineAsset.editorSettings.fps : TimelineAsset.EditorSettings.kDefaultFps; } + } + + bool selectionHasIncompatibleCapabilities + { + get + { + return !(m_SelectionInfo.supportsBlending + && m_SelectionInfo.supportsClipIn + && m_SelectionInfo.supportsExtrapolation + && m_SelectionInfo.supportsSpeedMultiplier); + } + } + + public override bool RequiresConstantRepaint() + { + return base.RequiresConstantRepaint() || (m_SelectedPlayableAssetsInspector != null && m_SelectedPlayableAssetsInspector.RequiresConstantRepaint()); + } + + internal override void OnHeaderTitleGUI(Rect titleRect, string header) + { + if (hasMultipleSelection) + { + base.OnHeaderTitleGUI(titleRect, m_MultiselectionHeaderTitle); + return; + } + + if (m_DisplayNameProperty != null) + { + using (new EditorGUI.DisabledScope(!IsEnabled())) + { + serializedObject.Update(); + if (IsLocked()) + { + base.OnHeaderTitleGUI(titleRect, m_DisplayNameProperty.stringValue); + } + else + { + EditorGUI.BeginChangeCheck(); + EditorGUI.DelayedTextField(titleRect, m_DisplayNameProperty, GUIContent.none); + if (EditorGUI.EndChangeCheck()) + { + ApplyModifiedProperties(); + TimelineWindow.RepaintIfEditingTimelineAsset(m_TimelineAsset); + } + } + } + } + } + + internal override Rect DrawHeaderHelpAndSettingsGUI(Rect r) + { + using (new EditorGUI.DisabledScope(IsLocked())) + { + var helpSize = EditorStyles.iconButton.CalcSize(EditorGUI.GUIContents.helpIcon); + const int kTopMargin = 5; + // Show Editor Header Items. + return EditorGUIUtility.DrawEditorHeaderItems(new Rect(r.xMax - helpSize.x, r.y + kTopMargin, helpSize.x, helpSize.y), targets); + } + } + + internal override void OnHeaderIconGUI(Rect iconRect) + { + using (new EditorGUI.DisabledScope(IsLocked())) + { + var bgColor = Color.white; + if (!EditorGUIUtility.isProSkin) + bgColor.a = 0.55f; + using (new GUIColorOverride(bgColor)) + { + GUI.Label(iconRect, Styles.TimelineClipBG); + } + + var fgColor = Color.white; + if (m_SelectionInfo != null && m_SelectionInfo.uniqueParentTracks.Count == 1) + fgColor = TrackResourceCache.GetTrackColor(m_SelectionInfo.uniqueParentTracks.First()); + + using (new GUIColorOverride(fgColor)) + { + GUI.Label(iconRect, Styles.TimelineClipFG); + } + } + } + + public void OnEnable() + { + m_ClipCurveEditor = new ClipInspectorCurveEditor(); + + m_SelectionCache = new List(); + var selectedClips = new List(); + foreach (var editorClipObject in targets) + { + var editorClip = editorClipObject as EditorClip; + if (editorClip != null) + { + //all selected clips should have the same TimelineAsset + if (!IsTimelineAssetValidForEditorClip(editorClip)) + { + m_SelectionCache.Clear(); + return; + } + m_SelectionCache.Add(new EditorClipSelection(editorClip)); + selectedClips.Add(editorClip.clip); + } + } + + InitializeProperties(); + m_SelectionInfo = new ClipInspectorSelectionInfo(selectedClips); + + if (m_SelectionInfo.selectedAssetTypesAreHomogeneous) + { + var selectedAssets = m_SelectionCache.Select(e => e.clip.asset).ToArray(); + m_SelectedPlayableAssetsInspector = TimelineInspectorUtility.GetInspectorForObjects(selectedAssets); + } + + m_MultiselectionHeaderTitle = m_SelectionCache.Count + " " + Styles.MultipleSelectionTitle.text; + m_ClipAssetTitle.text = PlayableAssetSectionTitle(); + } + + void DrawClipProperties() + { + var dirtyEditorClipSelection = m_SelectionCache.Where(s => s.editorClip.GetHashCode() != s.editorClip.lastHash); + UnselectCurves(); + + EditorGUI.BeginChangeCheck(); + + //Group Selection + if (hasMultipleSelection) + { + GUILayout.Label(Styles.GroupTimingTitle); + EditorGUI.indentLevel++; + DrawGroupSelectionProperties(); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + } + + //Draw clip timing + GUILayout.Label(Styles.ClipTimingTitle); + + if (hasMultipleSelection && selectionHasIncompatibleCapabilities) + { + GUILayout.Label(Styles.MultipleClipsSelectedIncompatibleCapabilitiesWarning, EditorStyles.helpBox); + } + + EditorGUI.indentLevel++; + + if (!m_SelectionInfo.containsAtLeastTwoClipsOnTheSameTrack) + { + DrawStartTimeField(); + DrawEndTimeField(); + } + + if (!hasMultipleSelection) + { + DrawDurationProperty(); + } + + if (m_SelectionInfo.supportsBlending) + { + EditorGUILayout.Space(); + DrawBlendingProperties(); + } + + if (m_SelectionInfo.supportsClipIn) + { + EditorGUILayout.Space(); + DrawClipInProperty(); + } + + if (!hasMultipleSelection && m_SelectionInfo.supportsSpeedMultiplier) + { + EditorGUILayout.Space(); + DrawTimeScale(); + } + + EditorGUI.indentLevel--; + + bool hasDirtyEditorClips = false; + foreach (var editorClipSelection in dirtyEditorClipSelection) + { + EditorUtility.SetDirty(editorClipSelection.editorClip); + hasDirtyEditorClips = true; + } + + //Re-evaluate the graph in case of a change in properties + bool propertiesHaveChanged = false; + if (EditorGUI.EndChangeCheck() || hasDirtyEditorClips) + { + if (TimelineWindow.IsEditingTimelineAsset(m_TimelineAsset) && TimelineWindow.instance.state != null) + { + TimelineWindow.instance.state.Evaluate(); + TimelineWindow.instance.Repaint(); + } + propertiesHaveChanged = true; + } + + //Draw Animation Extrapolation + if (m_SelectionInfo.supportsExtrapolation) + { + EditorGUILayout.Space(); + GUILayout.Label(Styles.AnimationExtrapolationTitle); + EditorGUI.indentLevel++; + DrawExtrapolationOptions(); + EditorGUI.indentLevel--; + } + + //Blend curves + if (m_SelectionInfo.supportsBlending) + { + EditorGUILayout.Space(); + GUILayout.Label(Styles.BlendCurvesTitle); + EditorGUI.indentLevel++; + DrawBlendOptions(); + EditorGUI.indentLevel--; + } + + EditorGUILayout.Space(); + + if (CanShowPlayableAssetInspector()) + { + DrawClipAssetGui(); + } + + if (propertiesHaveChanged) + { + foreach (var item in m_SelectionCache) + item.editorClip.lastHash = item.editorClip.GetHashCode(); + m_SelectionInfo.Update(); + } + } + + public override void OnInspectorGUI() + { + if (TimelineWindow.instance == null || m_TimelineAsset == null) + return; + + using (new EditorGUI.DisabledScope(IsLocked())) + { + EditMode.HandleModeClutch(); + + serializedObject.Update(); + DrawClipProperties(); + ApplyModifiedProperties(); + } + } + + internal override bool IsEnabled() + { + if (!TimelineUtility.IsCurrentSequenceValid() || IsCurrentSequenceReadOnly()) + return false; + + if (m_TimelineAsset != TimelineWindow.instance.state.editSequence.asset) + return false; + return base.IsEnabled(); + } + + void DrawTimeScale() + { + var inputEvent = InputEvent.None; + var newEndTime = m_SelectionInfo.end; + var oldTimeScale = m_TimeScaleProperty.doubleValue; + + EditorGUI.BeginChangeCheck(); + var newTimeScale = TimelineInspectorUtility.DelayedAndDraggableDoubleField(Styles.TimeScaleName, oldTimeScale, ref inputEvent, k_TimeScaleSensitivity); + + if (EditorGUI.EndChangeCheck()) + { + newTimeScale = newTimeScale.Clamp(TimelineClip.kTimeScaleMin, TimelineClip.kTimeScaleMax); + newEndTime = m_SelectionInfo.start + (m_SelectionInfo.duration * oldTimeScale / newTimeScale); + } + EditMode.inputHandler.ProcessTrim(inputEvent, newEndTime, true); + } + + void DrawStartTimeField() + { + var inputEvent = InputEvent.None; + var newStart = TimelineInspectorUtility.TimeFieldUsingTimeReference(Styles.StartName, m_SelectionInfo.multipleClipStart, false, m_SelectionInfo.hasMultipleStartValues, currentFrameRate, 0.0, TimelineClip.kMaxTimeValue, ref inputEvent); + + if (inputEvent.InputHasBegun() && m_SelectionInfo.hasMultipleStartValues) + { + var items = ItemsUtils.ToItems(m_SelectionInfo.clips); + EditMode.inputHandler.SetValueForEdge(items, AttractedEdge.Left, newStart); //if the field has multiple values, set the same start on all selected clips + m_SelectionInfo.Update(); //clips could have moved relative to each other, recalculate + } + + EditMode.inputHandler.ProcessMove(inputEvent, newStart); + } + + void DrawEndTimeField() + { + var inputEvent = InputEvent.None; + var newEndTime = TimelineInspectorUtility.TimeFieldUsingTimeReference(Styles.EndName, m_SelectionInfo.multipleClipEnd, false, m_SelectionInfo.hasMultipleEndValues, currentFrameRate, 0, TimelineClip.kMaxTimeValue, ref inputEvent); + + if (inputEvent.InputHasBegun() && m_SelectionInfo.hasMultipleEndValues) + { + var items = ItemsUtils.ToItems(m_SelectionInfo.clips); + EditMode.inputHandler.SetValueForEdge(items, AttractedEdge.Right, newEndTime); //if the field has multiple value, set the same end on all selected clips + m_SelectionInfo.Update(); //clips could have moved relative to each other, recalculate + } + + var newStartValue = m_SelectionInfo.multipleClipStart + (newEndTime - m_SelectionInfo.multipleClipEnd); + EditMode.inputHandler.ProcessMove(inputEvent, newStartValue); + } + + void DrawClipAssetGui() + { + const float labelIndent = 34; + if (m_SelectedPlayableAssetsInspector == null) + return; + + var rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.inspectorTitlebar); + var oldWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = rect.width - labelIndent; + m_IsClipAssetInspectorExpanded = EditorGUI.FoldoutTitlebar(rect, m_ClipAssetTitle, m_IsClipAssetInspectorExpanded, false); + EditorGUIUtility.labelWidth = oldWidth; + if (m_IsClipAssetInspectorExpanded) + { + EditorGUILayout.Space(); + EditorGUI.indentLevel++; + ShowPlayableAssetInspector(); + EditorGUI.indentLevel--; + } + } + + void DrawExtrapolationOptions() + { + EditorGUI.BeginChangeCheck(); + + // PreExtrapolation + var preExtrapolationTime = m_PreExtrapolationTimeProperty.doubleValue; + bool hasPreExtrap = preExtrapolationTime > 0.0; + if (hasPreExtrap) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(m_PreExtrapolationModeProperty, Styles.PreExtrapolateLabel); + using (new GUIMixedValueScope(m_PreExtrapolationTimeProperty.hasMultipleDifferentValues)) + EditorGUILayout.DoubleField(preExtrapolationTime, EditorStyles.label); + EditorGUILayout.EndHorizontal(); + } + + // PostExtrapolation + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(m_PostExtrapolationModeProperty, Styles.PostExtrapolateLabel); + using (new GUIMixedValueScope(m_PostExtrapolationTimeProperty.hasMultipleDifferentValues)) + EditorGUILayout.DoubleField(m_PostExtrapolationTimeProperty.doubleValue, EditorStyles.label); + EditorGUILayout.EndHorizontal(); + } + + if (EditorGUI.EndChangeCheck()) + { + // if these options change the interval tree may need to be rebuilt. + if (TimelineWindow.IsEditingTimelineAsset(m_TimelineAsset) && TimelineWindow.instance.state != null) + { + TimelineWindow.instance.state.Refresh(); + } + } + } + + void OnDestroy() + { + DestroyImmediate(m_SelectedPlayableAssetsInspector); + } + + public override GUIContent GetPreviewTitle() + { + return Styles.PreviewTitle; + } + + public override bool HasPreviewGUI() + { + return m_PreviewCurves != null; + } + + public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) + { + if (m_PreviewCurves != null && m_ClipCurveEditor != null) + { + SetCurveEditorTrackHead(); + m_ClipCurveEditor.OnGUI(r, m_CurvePresets); + } + } + + void SetCurveEditorTrackHead() + { + if (TimelineWindow.instance == null || TimelineWindow.instance.state == null) + return; + + if (hasMultipleSelection) + return; + + var editorClip = target as EditorClip; + if (editorClip == null) + return; + + var director = TimelineWindow.instance.state.editSequence.director; + + if (director == null) + return; + + m_ClipCurveEditor.trackTime = ClipInspectorCurveEditor.kDisableTrackTime; + } + + void UnselectCurves() + { + if (Event.current.type == EventType.MouseDown) + { + m_PreviewCurves = null; + if (m_ClipCurveEditor != null) + m_ClipCurveEditor.SetUpdateCurveCallback(null); + } + } + + // Callback when the mixin/mixout properties are clicked on + void OnMixCurveSelected(string title, CurvePresetLibrary library, SerializedProperty curveSelected, bool easeIn) + { + m_CurvePresets = library; + m_PreviewCurves = new[] { curveSelected.animationCurveValue }; + m_ClipCurveEditor.headerString = title; + m_ClipCurveEditor.SetCurves(m_PreviewCurves, null); + m_ClipCurveEditor.SetSelected(curveSelected.animationCurveValue); + if (easeIn) + m_ClipCurveEditor.SetUpdateCurveCallback(MixInCurveUpdated); + else + m_ClipCurveEditor.SetUpdateCurveCallback(MixOutCurveUpdated); + Repaint(); + } + + // callback when the mix property is updated + void MixInCurveUpdated(AnimationCurve curve, EditorCurveBinding binding) + { + curve.keys = CurveEditUtility.SanitizeCurveKeys(curve.keys, true); + m_MixInCurveProperty.animationCurveValue = curve; + serializedObject.ApplyModifiedProperties(); + var editorClip = target as EditorClip; + if (editorClip != null) + editorClip.lastHash = editorClip.GetHashCode(); + RefreshCurves(); + } + + void MixOutCurveUpdated(AnimationCurve curve, EditorCurveBinding binding) + { + curve.keys = CurveEditUtility.SanitizeCurveKeys(curve.keys, false); + m_MixOutCurveProperty.animationCurveValue = curve; + serializedObject.ApplyModifiedProperties(); + var editorClip = target as EditorClip; + if (editorClip != null) + editorClip.lastHash = editorClip.GetHashCode(); + RefreshCurves(); + } + + void RefreshCurves() + { + AnimationCurvePreviewCache.ClearCache(); + TimelineWindow.RepaintIfEditingTimelineAsset(m_TimelineAsset); + Repaint(); + } + + void DrawBlendCurve(GUIContent title, SerializedProperty modeProperty, SerializedProperty curveProperty, Action onCurveClick) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PropertyField(modeProperty, title); + if (hasMultipleSelection) + { + GUILayout.FlexibleSpace(); + } + else + { + using (new EditorGUI.DisabledScope(modeProperty.intValue != (int)TimelineClip.BlendCurveMode.Manual)) + { + ClipInspectorCurveEditor.CurveField(GUIContent.none, curveProperty, onCurveClick); + } + } + + EditorGUILayout.EndHorizontal(); + } + + void ShowPlayableAssetInspector() + { + if (!m_SelectionInfo.selectedAssetTypesAreHomogeneous) + return; + + if (m_SelectedPlayableAssetsInspector != null) + { + foreach (var selectedItem in m_SelectionCache) + CurvesOwnerInspectorHelper.PreparePlayableAsset(selectedItem); + + EditorGUI.BeginChangeCheck(); + using (new EditorGUI.DisabledScope(IsLocked())) + { + m_SelectedPlayableAssetsInspector.OnInspectorGUI(); + } + if (EditorGUI.EndChangeCheck()) + { + MarkClipsDirty(); + if (TimelineWindow.IsEditingTimelineAsset(m_TimelineAsset) && TimelineWindow.instance.state != null) + { + var basicInspector = m_SelectedPlayableAssetsInspector as BasicAssetInspector; + if (basicInspector != null) + basicInspector.ApplyChanges(); + else + TimelineEditor.Refresh(RefreshReason.ContentsModified); + } + } + } + } + + void ApplyModifiedProperties() + { + // case 926861 - we need to force the track to be dirty since modifying the clip does not + // automatically mark the track asset as dirty + if (serializedObject.ApplyModifiedProperties()) + { + foreach (var obj in serializedObject.targetObjects) + { + var editorClip = obj as EditorClip; + if (editorClip != null && editorClip.clip != null && editorClip.clip.parentTrack != null) + { + editorClip.clip.MarkDirty(); + EditorUtility.SetDirty(editorClip.clip.parentTrack); + } + } + } + } + + void MarkClipsDirty() + { + foreach (var obj in targets) + { + var editorClip = obj as EditorClip; + if (editorClip != null && editorClip.clip != null) + { + editorClip.clip.MarkDirty(); + } + } + } + + string PlayableAssetSectionTitle() + { + var firstSelectedClipAsset = m_SelectionCache.Any() ? m_SelectionCache.First().clip.asset : null; + return firstSelectedClipAsset != null + ? ObjectNames.NicifyVariableName(firstSelectedClipAsset.GetType().Name) + : string.Empty; + } + + bool IsTimelineAssetValidForEditorClip(EditorClip editorClip) + { + var trackAsset = editorClip.clip.parentTrack; + if (trackAsset == null) + return false; + + var clipTimelineAsset = trackAsset.timelineAsset; + if (m_TimelineAsset == null) + m_TimelineAsset = clipTimelineAsset; + else if (clipTimelineAsset != m_TimelineAsset) + { + m_TimelineAsset = null; + return false; + } + return true; + } + + bool CanShowPlayableAssetInspector() + { + if (hasMultipleSelection) + return m_SelectedPlayableAssetsInspector != null && + m_SelectedPlayableAssetsInspector.canEditMultipleObjects && + m_SelectionInfo.selectedAssetTypesAreHomogeneous; + else + return true; + } + + void DrawDurationProperty() + { + var minDuration = 1.0 / 30.0; + if (currentFrameRate > float.Epsilon) + { + minDuration = 1.0 / currentFrameRate; + } + + var inputEvent = InputEvent.None; + var newDuration = TimelineInspectorUtility.DurationFieldUsingTimeReference( + Styles.DurationName, m_SelectionInfo.start, m_SelectionInfo.end, false, m_SelectionInfo.hasMultipleDurationValues, currentFrameRate, minDuration, TimelineClip.kMaxTimeValue, ref inputEvent); + EditMode.inputHandler.ProcessTrim(inputEvent, m_SelectionInfo.start + newDuration, false); + } + + void DrawBlendingProperties() + { + var useBlendIn = m_SelectionInfo.hasBlendIn; + var maxBlendDuration = m_SelectionInfo.smallestDuration * 0.49; + var blendMax = useBlendIn ? TimelineClip.kMaxTimeValue : maxBlendDuration; + var inputEvent = InputEvent.None; + + TimelineInspectorUtility.TimeField(useBlendIn + ? m_BlendInDurationProperty + : m_EaseInDurationProperty, Styles.EaseInDurationName, useBlendIn, currentFrameRate, 0, blendMax, ref inputEvent); + + var useBlendOut = m_SelectionInfo.hasBlendOut; + blendMax = useBlendOut ? TimelineClip.kMaxTimeValue : maxBlendDuration; + TimelineInspectorUtility.TimeField(useBlendOut + ? m_BlendOutDurationProperty + : m_EaseOutDurationProperty, Styles.EaseOutDurationName, useBlendOut, currentFrameRate, 0, blendMax, ref inputEvent); + } + + void DrawClipInProperty() + { + var action = InputEvent.None; + TimelineInspectorUtility.TimeField(m_ClipInProperty, Styles.ClipInName, false, currentFrameRate, 0, TimelineClip.kMaxTimeValue, ref action); + } + + void DrawBlendOptions() + { + EditorGUI.BeginChangeCheck(); + + DrawBlendCurve(Styles.BlendInCurveName, m_BlendInCurveModeProperty, m_MixInCurveProperty, x => OnMixCurveSelected("Blend In", BuiltInPresets.blendInPresets, x, true)); + DrawBlendCurve(Styles.BlendOutCurveName, m_BlendOutCurveModeProperty, m_MixOutCurveProperty, x => OnMixCurveSelected("Blend Out", BuiltInPresets.blendOutPresets, x, false)); + + if (EditorGUI.EndChangeCheck()) + TimelineWindow.RepaintIfEditingTimelineAsset(m_TimelineAsset); + } + + void DrawGroupSelectionProperties() + { + var inputEvent = InputEvent.None; + var newStartTime = TimelineInspectorUtility.TimeField(Styles.MultipleClipStartName, m_SelectionInfo.multipleClipStart, false, false, currentFrameRate, 0, TimelineClip.kMaxTimeValue, ref inputEvent); + EditMode.inputHandler.ProcessMove(inputEvent, newStartTime); + + inputEvent = InputEvent.None; + var newEndTime = TimelineInspectorUtility.TimeField(Styles.MultipleClipEndName, m_SelectionInfo.multipleClipEnd, false, false, currentFrameRate, 0, TimelineClip.kMaxTimeValue, ref inputEvent); + var newStartValue = newStartTime + (newEndTime - m_SelectionInfo.multipleClipEnd); + EditMode.inputHandler.ProcessMove(inputEvent, newStartValue); + } + + bool IsLocked() + { + if (!TimelineUtility.IsCurrentSequenceValid() || IsCurrentSequenceReadOnly()) + return true; + + return targets.OfType().Any(t => t.clip.parentTrack != null && t.clip.parentTrack.lockedInHierarchy); + } + + static bool IsCurrentSequenceReadOnly() + { + return TimelineWindow.instance.state.editSequence.isReadOnly; + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs.meta new file mode 100644 index 0000000..165a3ea --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspector.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dff73c4907c95264c8fc095a81f9d51e +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/inspectors/ClipInspector/ClipInspectorCurveEditor.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs new file mode 100644 index 0000000..e4c5ca5 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEditorInternal; +using UnityEngine; + +namespace UnityEditor.Timeline +{ + class ClipInspectorCurveEditor + { + CurveEditor m_CurveEditor; + + AnimationCurve[] m_Curves; + CurveWrapper[] m_CurveWrappers; + + const float k_HeaderHeight = 30; + const float k_PresetHeight = 30; + + Action m_CurveUpdatedCallback; + GUIContent m_TextContent = new GUIContent(); + + GUIStyle m_LabelStyle; + GUIStyle m_LegendStyle; + + // Track time. controls the position of the track head + public static readonly double kDisableTrackTime = double.NaN; + double m_trackTime = kDisableTrackTime; + public double trackTime { get { return m_trackTime; } set { m_trackTime = value; } } + + public string headerString { get; set; } + + public ClipInspectorCurveEditor() + { + var curveEditorSettings = new CurveEditorSettings + { + allowDeleteLastKeyInCurve = false, + allowDraggingCurvesAndRegions = true, + hTickLabelOffset = 0.1f, + showAxisLabels = true, + useFocusColors = false, + wrapColor = new EditorGUIUtility.SkinnedColor(Color.black), + hSlider = false, + hRangeMin = 0.0f, + vRangeMin = 0.0F, + vRangeMax = 1.0f, + hRangeMax = 1.0F, + vSlider = false, + hRangeLocked = false, + vRangeLocked = false, + + hTickStyle = new TickStyle + { + tickColor = new EditorGUIUtility.SkinnedColor(new Color(0.0f, 0.0f, 0.0f, 0.2f)), + distLabel = 30, + stubs = false, + centerLabel = true + }, + + vTickStyle = new TickStyle + { + tickColor = new EditorGUIUtility.SkinnedColor(new Color(1.0f, 0.0f, 0.0f, 0.2f)), + distLabel = 20, + stubs = false, + centerLabel = true + } + }; + + m_CurveEditor = new CurveEditor(new Rect(0, 0, 1000, 100), new CurveWrapper[0], true) + { + settings = curveEditorSettings, + ignoreScrollWheelUntilClicked = true + }; + } + + internal bool InitStyles() + { + if (EditorStyles.s_Current == null) + return false; + + if (m_LabelStyle == null) + { + m_LabelStyle = new GUIStyle(EditorStyles.whiteLargeLabel); + m_LegendStyle = new GUIStyle(EditorStyles.miniBoldLabel); + + m_LabelStyle.alignment = TextAnchor.MiddleCenter; + m_LegendStyle.alignment = TextAnchor.MiddleCenter; + } + return true; + } + + internal void OnGUI(Rect clientRect, CurvePresetLibrary presets) + { + const float presetPad = 30.0f; + + if (!InitStyles()) + return; + + if (m_Curves == null || m_Curves.Length == 0) + return; + + // regions + var headerRect = new Rect(clientRect.x, clientRect.y, clientRect.width, k_HeaderHeight); + var curveRect = new Rect(clientRect.x, clientRect.y + headerRect.height, clientRect.width, clientRect.height - k_HeaderHeight - k_PresetHeight); + var presetRect = new Rect(clientRect.x + presetPad, clientRect.y + curveRect.height + k_HeaderHeight, clientRect.width - presetPad, k_PresetHeight); + + GUI.Box(headerRect, headerString, m_LabelStyle); + + //Case 1201474 : Force to update only when Repaint event is called as the new rect provided on other event create a wrong curve editor computation. + if (Event.current.type == EventType.Repaint) + { + m_CurveEditor.rect = curveRect; + m_CurveEditor.shownAreaInsideMargins = new Rect(0, 0, 1, 1); + } + m_CurveEditor.animationCurves = m_CurveWrappers; + UpdateSelectionColors(); + + DrawTrackHead(curveRect); + + EditorGUI.BeginChangeCheck(); + + m_CurveEditor.OnGUI(); + DrawPresets(presetRect, presets); + + bool hasChanged = EditorGUI.EndChangeCheck(); + + if (presets == null) + DrawLegend(presetRect); + + if (hasChanged) + ProcessUpdates(); + } + + void DrawPresets(Rect position, PresetLibrary curveLibrary) + { + if (curveLibrary == null || curveLibrary.Count() == 0) + return; + + const int maxNumPresets = 9; + int numPresets = curveLibrary.Count(); + int showNumPresets = Mathf.Min(numPresets, maxNumPresets); + + const float swatchWidth = 30; + const float swatchHeight = 15; + const float spaceBetweenSwatches = 10; + float presetButtonsWidth = showNumPresets * swatchWidth + (showNumPresets - 1) * spaceBetweenSwatches; + float flexWidth = (position.width - presetButtonsWidth) * 0.5f; + + // Preset swatch area + float curY = (position.height - swatchHeight) * 0.5f; + float curX = 3.0f; + if (flexWidth > 0) + curX = flexWidth; + + GUI.BeginGroup(position); + + for (int i = 0; i < showNumPresets; i++) + { + if (i > 0) + curX += spaceBetweenSwatches; + + var swatchRect = new Rect(curX, curY, swatchWidth, swatchHeight); + m_TextContent.tooltip = curveLibrary.GetName(i); + if (GUI.Button(swatchRect, m_TextContent, GUIStyle.none)) + { + // if there is only 1, no need to specify + IEnumerable wrappers = m_CurveWrappers; + if (m_CurveWrappers.Length > 1) + wrappers = m_CurveWrappers.Where(x => x.selected == CurveWrapper.SelectionMode.Selected); + + foreach (var wrapper in wrappers) + { + var presetCurve = (AnimationCurve)curveLibrary.GetPreset(i); + wrapper.curve.keys = (Keyframe[])presetCurve.keys.Clone(); + wrapper.changed = true; + } + } + + if (Event.current.type == EventType.Repaint) + curveLibrary.Draw(swatchRect, i); + + curX += swatchWidth; + } + + GUI.EndGroup(); + } + + // draw a line representing where in the current clip we are + void DrawTrackHead(Rect clientRect) + { + DirectorStyles styles = TimelineWindow.styles; + if (styles == null) + return; + + if (!double.IsNaN(m_trackTime)) + { + float x = m_CurveEditor.TimeToPixel((float)m_trackTime, clientRect); + x = Mathf.Clamp(x, clientRect.xMin, clientRect.xMax); + var p1 = new Vector2(x, clientRect.yMin); + var p2 = new Vector2(x, clientRect.yMax); + Graphics.DrawLine(p1, p2, DirectorStyles.Instance.customSkin.colorPlayhead); + } + } + + // Draws a legend for the displayed curves + void DrawLegend(Rect r) + { + if (m_CurveWrappers == null || m_CurveWrappers.Length == 0) + return; + + Color c = GUI.color; + float boxWidth = r.width / m_CurveWrappers.Length; + for (int i = 0; i < m_CurveWrappers.Length; i++) + { + CurveWrapper cw = m_CurveWrappers[i]; + if (cw != null) + { + var pos = new Rect(r.x + i * boxWidth, r.y, boxWidth, r.height); + var textColor = cw.color; + textColor.a = 1; + GUI.color = textColor; + string name = LabelName(cw.binding.propertyName); + EditorGUI.LabelField(pos, name, m_LegendStyle); + } + } + GUI.color = c; + } + + // Helper for making label name appropriately small + static char[] s_LabelMarkers = { '_' }; + + static string LabelName(string propertyName) + { + propertyName = AnimationWindowUtility.GetPropertyDisplayName(propertyName); + int index = propertyName.LastIndexOfAny(s_LabelMarkers); + if (index >= 0) + propertyName = propertyName.Substring(index); + return propertyName; + } + + public void SetCurves(AnimationCurve[] curves, EditorCurveBinding[] bindings) + { + m_Curves = curves; + if (m_Curves != null && m_Curves.Length > 0) + { + m_CurveWrappers = new CurveWrapper[m_Curves.Length]; + for (int i = 0; i < m_Curves.Length; i++) + { + var cw = new CurveWrapper + { + renderer = new NormalCurveRenderer(m_Curves[i]), + readOnly = false, + color = EditorGUI.kCurveColor, + id = curves[i].GetHashCode(), + hidden = false, + regionId = -1 + }; + + cw.renderer.SetWrap(WrapMode.Clamp, WrapMode.Clamp); + cw.renderer.SetCustomRange(0, 1); + + if (bindings != null) + { + cw.binding = bindings[i]; + cw.color = CurveUtility.GetPropertyColor(bindings[i].propertyName); + cw.id = bindings[i].GetHashCode(); + } + + m_CurveWrappers[i] = cw; + } + + UpdateSelectionColors(); + m_CurveEditor.animationCurves = m_CurveWrappers; + } + } + + internal void SetUpdateCurveCallback(Action callback) + { + m_CurveUpdatedCallback = callback; + } + + void ProcessUpdates() + { + foreach (var cw in m_CurveWrappers) + { + if (cw.changed) + { + cw.changed = false; + + if (m_CurveUpdatedCallback != null) + m_CurveUpdatedCallback(cw.curve, cw.binding); + } + } + } + + public void SetSelected(AnimationCurve curve) + { + m_CurveEditor.SelectNone(); + for (int i = 0; i < m_Curves.Length; i++) + { + if (curve == m_Curves[i]) + { + m_CurveWrappers[i].selected = CurveWrapper.SelectionMode.Selected; + m_CurveEditor.AddSelection(new CurveSelection(m_CurveWrappers[i].id, 0)); + } + } + + UpdateSelectionColors(); + } + + void UpdateSelectionColors() + { + if (m_CurveWrappers == null) + return; + + // manually manage selection colors + foreach (var cw in m_CurveWrappers) + { + Color c = cw.color; + if (cw.readOnly) + c.a = 0.75f; + else if (cw.selected != CurveWrapper.SelectionMode.None) + c.a = 1.0f; + else + c.a = 0.5f; + cw.color = c; + } + } + + public static void CurveField(GUIContent title, SerializedProperty property, Action onClick) + { + Rect controlRect = EditorGUILayout.GetControlRect(GUILayout.MinWidth(20)); + EditorGUI.BeginProperty(controlRect, title, property); + DrawCurve(controlRect, property, onClick, EditorGUI.kCurveColor, EditorGUI.kCurveBGColor); + EditorGUI.EndProperty(); + } + + static Rect DrawCurve(Rect controlRect, SerializedProperty property, Action onClick, Color fgColor, Color bgColor) + { + if (GUI.Button(controlRect, GUIContent.none)) + { + if (onClick != null) + onClick(property); + } + EditorGUIUtility.DrawCurveSwatch(controlRect, null, property, fgColor, bgColor); + return controlRect; + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs.meta new file mode 100644 index 0000000..1d16576 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorCurveEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d3d14fa8f6934e14d92e37279e40e89b +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/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs new file mode 100644 index 0000000..7c2d088 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UnityEngine.Timeline; + +namespace UnityEditor.Timeline +{ + class ClipInspectorSelectionInfo + { + public double start, end, duration; + public double multipleClipStart, multipleClipEnd; + public double smallestDuration; + + public bool hasMultipleStartValues, hasMultipleEndValues, hasMultipleDurationValues; + public bool supportsExtrapolation, supportsClipIn, supportsSpeedMultiplier, supportsBlending; + public bool hasBlendIn, hasBlendOut; + public bool selectedAssetTypesAreHomogeneous; + public bool containsAtLeastTwoClipsOnTheSameTrack; + + public HashSet uniqueParentTracks = new HashSet(); + public ICollection clips { get; private set; } + + public ClipInspectorSelectionInfo(ICollection selectedClips) + { + supportsBlending = supportsClipIn = supportsExtrapolation = supportsSpeedMultiplier = true; + hasBlendIn = hasBlendOut = true; + selectedAssetTypesAreHomogeneous = true; + smallestDuration = TimelineClip.kMaxTimeValue; + start = end = duration = 0; + multipleClipStart = multipleClipEnd = 0; + hasMultipleStartValues = hasMultipleEndValues = hasMultipleDurationValues = false; + containsAtLeastTwoClipsOnTheSameTrack = false; + + clips = selectedClips; + Build(); + } + + void Build() + { + if (!clips.Any()) return; + + var firstSelectedClip = clips.First(); + if (firstSelectedClip == null) return; + + var firstSelectedClipAssetType = firstSelectedClip.asset != null ? firstSelectedClip.asset.GetType() : null; + + smallestDuration = TimelineClip.kMaxTimeValue; + InitSelectionBounds(firstSelectedClip); + InitMultipleClipBounds(firstSelectedClip); + + foreach (var clip in clips) + { + if (clip == null) continue; + + uniqueParentTracks.Add(clip.parentTrack); + selectedAssetTypesAreHomogeneous &= clip.asset.GetType() == firstSelectedClipAssetType; + + UpdateClipCaps(clip); + UpdateBlends(clip); + UpdateSmallestDuration(clip); + UpdateMultipleValues(clip); + UpdateMultipleValues(clip); + } + containsAtLeastTwoClipsOnTheSameTrack = uniqueParentTracks.Count != clips.Count; + } + + public void Update() + { + var firstSelectedClip = clips.First(); + if (firstSelectedClip == null) return; + + hasBlendIn = hasBlendOut = true; + hasMultipleStartValues = hasMultipleDurationValues = hasMultipleEndValues = false; + smallestDuration = TimelineClip.kMaxTimeValue; + InitSelectionBounds(firstSelectedClip); + InitMultipleClipBounds(firstSelectedClip); + + foreach (var clip in clips) + { + if (clip == null) continue; + + UpdateBlends(clip); + UpdateSmallestDuration(clip); + UpdateMultipleValues(clip); + } + } + + void InitSelectionBounds(TimelineClip clip) + { + start = clip.start; + duration = clip.duration; + end = clip.start + clip.duration; + } + + void InitMultipleClipBounds(TimelineClip firstSelectedClip) + { + multipleClipStart = firstSelectedClip.start; + multipleClipEnd = end; + } + + void UpdateSmallestDuration(TimelineClip clip) + { + smallestDuration = Math.Min(smallestDuration, clip.duration); + } + + void UpdateClipCaps(TimelineClip clip) + { + supportsBlending &= clip.SupportsBlending(); + supportsClipIn &= clip.SupportsClipIn(); + supportsExtrapolation &= clip.SupportsExtrapolation(); + supportsSpeedMultiplier &= clip.SupportsSpeedMultiplier(); + } + + void UpdateMultipleValues(TimelineClip clip) + { + hasMultipleStartValues |= !Mathf.Approximately((float)clip.start, (float)start); + hasMultipleDurationValues |= !Mathf.Approximately((float)clip.duration, (float)duration); + var clipEnd = clip.start + clip.duration; + hasMultipleEndValues |= !Mathf.Approximately((float)clipEnd, (float)end); + + multipleClipStart = Math.Min(multipleClipStart, clip.start); + multipleClipEnd = Math.Max(multipleClipEnd, clip.end); + } + + void UpdateBlends(TimelineClip clip) + { + hasBlendIn &= clip.hasBlendIn; + hasBlendOut &= clip.hasBlendOut; + } + } +} diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs.meta b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs.meta new file mode 100644 index 0000000..bd8f85e --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/inspectors/ClipInspector/ClipInspectorSelectionInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 57a39be2178cca94ab21e15c082e3ab6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: -- cgit v1.2.3