123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- using System.Collections.Generic;
- using System.Linq;
- using JetBrains.Annotations;
- using UnityEditor.Timeline.Actions;
- using UnityEngine;
- using UnityEngine.Timeline;
- using UnityEngine.Playables;
-
- namespace UnityEditor.Timeline
- {
- [MenuEntry("Edit in Animation Window", MenuPriority.ClipEditActionSection.editInAnimationWindow), UsedImplicitly]
- class EditClipInAnimationWindow : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- if (!GetEditableClip(clips, out _, out _))
- return ActionValidity.NotApplicable;
- return ActionValidity.Valid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- TimelineClip clip;
- AnimationClip clipToEdit;
- if (!GetEditableClip(clips, out clip, out clipToEdit))
- return false;
-
- GameObject gameObject = null;
- if (TimelineEditor.inspectedDirector != null)
- gameObject = TimelineUtility.GetSceneGameObject(TimelineEditor.inspectedDirector, clip.GetParentTrack());
-
- var timeController = TimelineAnimationUtilities.CreateTimeController(clip);
- TimelineAnimationUtilities.EditAnimationClipWithTimeController(
- clipToEdit, timeController, clip.animationClip != null ? gameObject : null);
-
- return true;
- }
-
- private static bool GetEditableClip(IEnumerable<TimelineClip> clips, out TimelineClip clip, out AnimationClip animClip)
- {
- clip = null;
- animClip = null;
-
- if (clips.Count() != 1)
- return false;
-
- clip = clips.FirstOrDefault();
- if (clip == null)
- return false;
-
- if (clip.animationClip != null)
- animClip = clip.animationClip;
- else if (clip.curves != null && !clip.curves.empty)
- animClip = clip.curves;
-
- return animClip != null;
- }
- }
-
- [MenuEntry("Edit Sub-Timeline", MenuPriority.ClipEditActionSection.editSubTimeline), UsedImplicitly]
- class EditSubTimeline : ClipAction
- {
- private static readonly string MultiItemPrefix = "Edit Sub-Timelines/";
- private static readonly string SingleItemPrefix = "Edit ";
-
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- if (clips == null || clips.Count() != 1 || TimelineEditor.inspectedDirector == null)
- return ActionValidity.NotApplicable;
-
- var clip = clips.First();
- var directors = TimelineUtility.GetSubTimelines(clip, TimelineEditor.inspectedDirector);
- return directors.Any(x => x != null) ? ActionValidity.Valid : ActionValidity.NotApplicable;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- if (Validate(clips) != ActionValidity.Valid) return false;
-
- var clip = clips.First();
-
- var directors = TimelineUtility.GetSubTimelines(clip, TimelineEditor.inspectedDirector);
- ExecuteInternal(directors, 0, clip);
-
- return true;
- }
-
- static void ExecuteInternal(IList<PlayableDirector> directors, int directorIndex, TimelineClip clip)
- {
- SelectionManager.Clear();
- TimelineWindow.instance.SetCurrentTimeline(directors[directorIndex], clip);
- }
-
- internal void AddMenuItem(List<MenuActionItem> menuItems)
- {
- var clips = TimelineEditor.selectedClips;
- if (clips == null || clips.Length != 1)
- return;
-
- var mode = TimelineWindow.instance.currentMode.mode;
- MenuEntryAttribute menuAttribute = GetType().GetCustomAttributes(typeof(MenuEntryAttribute), false).OfType<MenuEntryAttribute>().FirstOrDefault();
- var menuItem = new MenuActionItem()
- {
- category = menuAttribute.subMenuPath ?? string.Empty,
- entryName = menuAttribute.name,
- isActiveInMode = this.IsActionActiveInMode(mode),
- priority = menuAttribute.priority,
- state = Validate(clips),
- callback = null
- };
-
- var subDirectors = TimelineUtility.GetSubTimelines(clips[0], TimelineEditor.inspectedDirector);
- if (subDirectors.Count == 1)
- {
- menuItem.entryName = SingleItemPrefix + DisplayNameHelper.GetDisplayName(subDirectors[0]);
- menuItem.callback = () =>
- {
- Execute(clips);
- };
- menuItems.Add(menuItem);
- }
- else
- {
- for (int i = 0; i < subDirectors.Count; i++)
- {
- var index = i;
- menuItem.category = MultiItemPrefix;
- menuItem.entryName = DisplayNameHelper.GetDisplayName(subDirectors[i]);
- menuItem.callback = () =>
- {
- ExecuteInternal(subDirectors, index, clips[0]);
- };
- menuItems.Add(menuItem);
- }
- }
- }
- }
-
- [MenuEntry("Editing/Trim Start", MenuPriority.ClipActionSection.trimStart)]
- [Shortcut(Shortcuts.Clip.trimStart), UsedImplicitly]
- class TrimStart : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- return clips.All(x => TimelineEditor.inspectedSequenceTime <= x.start || TimelineEditor.inspectedSequenceTime >= x.start + x.duration) ? ActionValidity.Invalid : ActionValidity.Valid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.TrimStart(clips, TimelineEditor.inspectedSequenceTime);
- }
- }
-
- [MenuEntry("Editing/Trim End", MenuPriority.ClipActionSection.trimEnd), UsedImplicitly]
- [Shortcut(Shortcuts.Clip.trimEnd)]
- class TrimEnd : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- return clips.All(x => TimelineEditor.inspectedSequenceTime <= x.start || TimelineEditor.inspectedSequenceTime >= x.start + x.duration) ? ActionValidity.Invalid : ActionValidity.Valid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.TrimEnd(clips, TimelineEditor.inspectedSequenceTime);
- }
- }
-
- [Shortcut(Shortcuts.Clip.split)]
- [MenuEntry("Editing/Split", MenuPriority.ClipActionSection.split), UsedImplicitly]
- class Split : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- return clips.All(x => TimelineEditor.inspectedSequenceTime <= x.start || TimelineEditor.inspectedSequenceTime >= x.start + x.duration) ? ActionValidity.Invalid : ActionValidity.Valid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- bool success = ClipModifier.Split(clips, TimelineEditor.inspectedSequenceTime, TimelineEditor.inspectedDirector);
- if (success)
- TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
- return success;
- }
- }
-
- [MenuEntry("Editing/Complete Last Loop", MenuPriority.ClipActionSection.completeLastLoop), UsedImplicitly]
- class CompleteLastLoop : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration);
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.CompleteLastLoop(clips);
- }
- }
-
- [MenuEntry("Editing/Trim Last Loop", MenuPriority.ClipActionSection.trimLastLoop), UsedImplicitly]
- class TrimLastLoop : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration);
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.TrimLastLoop(clips);
- }
- }
-
- [MenuEntry("Editing/Match Duration", MenuPriority.ClipActionSection.matchDuration), UsedImplicitly]
- class MatchDuration : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- return clips.Count() > 1 ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.MatchDuration(clips);
- }
- }
-
- [MenuEntry("Editing/Double Speed", MenuPriority.ClipActionSection.doubleSpeed), UsedImplicitly]
- class DoubleSpeed : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.All(x => x.SupportsSpeedMultiplier());
-
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.DoubleSpeed(clips);
- }
- }
-
- [MenuEntry("Editing/Half Speed", MenuPriority.ClipActionSection.halfSpeed), UsedImplicitly]
- class HalfSpeed : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.All(x => x.SupportsSpeedMultiplier());
-
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.HalfSpeed(clips);
- }
- }
-
- [MenuEntry("Editing/Reset Duration", MenuPriority.ClipActionSection.resetDuration), UsedImplicitly]
- class ResetDuration : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration);
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.ResetEditing(clips);
- }
- }
-
- [MenuEntry("Editing/Reset Speed", MenuPriority.ClipActionSection.resetSpeed), UsedImplicitly]
- class ResetSpeed : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.All(x => x.SupportsSpeedMultiplier());
-
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.ResetSpeed(clips);
- }
- }
-
- [MenuEntry("Editing/Reset All", MenuPriority.ClipActionSection.resetAll), UsedImplicitly]
- class ResetAll : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- bool canDisplay = clips.Any(TimelineHelpers.HasUsableAssetDuration) || clips.All(x => x.SupportsSpeedMultiplier());
-
- return canDisplay ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- var speedResult = ClipModifier.ResetSpeed(clips);
- var editResult = ClipModifier.ResetEditing(clips);
- return speedResult || editResult;
- }
- }
-
- [MenuEntry("Tile", MenuPriority.ClipActionSection.tile), UsedImplicitly]
- class Tile : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- return clips.Count() > 1 ? ActionValidity.Valid : ActionValidity.Invalid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- return ClipModifier.Tile(clips);
- }
- }
-
- [MenuEntry("Find Source Asset", MenuPriority.ClipActionSection.findSourceAsset), UsedImplicitly]
- [ActiveInMode(TimelineModes.Default | TimelineModes.ReadOnly)]
- class FindSourceAsset : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips)
- {
- if (clips.Count() > 1)
- return ActionValidity.Invalid;
-
- if (GetUnderlyingAsset(clips.First()) == null)
- return ActionValidity.Invalid;
-
- return ActionValidity.Valid;
- }
-
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- EditorGUIUtility.PingObject(GetUnderlyingAsset(clips.First()));
- return true;
- }
-
- private static UnityEngine.Object GetExternalPlayableAsset(TimelineClip clip)
- {
- if (clip.asset == null)
- return null;
-
- if ((clip.asset.hideFlags & HideFlags.HideInHierarchy) != 0)
- return null;
-
- return clip.asset;
- }
-
- private static UnityEngine.Object GetUnderlyingAsset(TimelineClip clip)
- {
- var asset = clip.asset as ScriptableObject;
- if (asset == null)
- return null;
-
- var fields = ObjectReferenceField.FindObjectReferences(asset.GetType());
- if (fields.Length == 0)
- return GetExternalPlayableAsset(clip);
-
- // Find the first non-null field
- foreach (var field in fields)
- {
- // skip scene refs in asset mode
- if (TimelineEditor.inspectedDirector == null && field.isSceneReference)
- continue;
- var obj = field.Find(asset, TimelineEditor.inspectedDirector);
- if (obj != null)
- return obj;
- }
-
- return GetExternalPlayableAsset(clip);
- }
- }
-
- class CopyClipsToClipboard : ClipAction
- {
- public override ActionValidity Validate(IEnumerable<TimelineClip> clips) => ActionValidity.Valid;
- public override bool Execute(IEnumerable<TimelineClip> clips)
- {
- TimelineEditor.clipboard.CopyItems(clips.ToItems());
- return true;
- }
- }
- }
|