Пример #1
0
        public void FinializeTrack(TrackAsset track, WindowState state)
        {
            // make sure we dirty the clip if we are in non clip mode
            var animTrack = track as AnimationTrack;

            if (!animTrack.inClipMode)
            {
                EditorUtility.SetDirty(animTrack.GetOrCreateClip());
            }

            // in clip mode we need to do some extra work
            if (recordClip != null)
            {
                // stretch the clip out to meet the new recording time
                if (m_ClipTime > recordClip.duration)
                {
                    UndoExtensions.RegisterTrack(track, "Add Key");
                    recordClip.duration = m_ClipTime;
                }

                track.CalculateExtrapolationTimes();
            }

            recordClip = null;
            m_ClipTime = 0;
            if (m_needRebuildRects)
            {
                state.CalculateRowRects();
                m_needRebuildRects = false;
            }
        }
Пример #2
0
        public static bool Tile(IEnumerable <TimelineClip> clips)
        {
            if (clips.Count() < 2)
            {
                return(false);
            }

            var clipsByTracks = clips.GroupBy(x => x.GetParentTrack())
                                .Select(track => new { track.Key, Items = track.OrderBy(c => c.start) });

            foreach (var track in clipsByTracks)
            {
                UndoExtensions.RegisterTrack(track.Key, L10n.Tr("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 void Drop()
        {
            if (IsValidDrop())
            {
                foreach (var grabbedItems in movingItems)
                {
                    var track = grabbedItems.targetTrack;
                    UndoExtensions.RegisterTrack(track, L10n.Tr("Move Items"));

                    if (EditModeUtils.IsInfiniteTrack(track) && grabbedItems.clips.Any())
                    {
                        ((AnimationTrack)track).ConvertToClipMode();
                    }
                }

                EditMode.FinishMove();

                Done();
            }
            else
            {
                Cancel();
            }

            EditMode.ClearEditMode();
        }
        internal static void ConvertFromClipMode(this AnimationTrack track, TimelineAsset timeline)
        {
            if (!track.CanConvertFromClipMode())
            {
                return;
            }

            UndoExtensions.RegisterTrack(track, L10n.Tr("Convert From Clip"));

            var clip  = track.clips[0];
            var delta = (float)clip.start;

            track.infiniteClipTimeOffset        = 0.0f;
            track.infiniteClipPreExtrapolation  = clip.preExtrapolationMode;
            track.infiniteClipPostExtrapolation = clip.postExtrapolationMode;

            var animAsset = clip.asset as AnimationPlayableAsset;

            if (animAsset)
            {
                track.infiniteClipOffsetPosition    = animAsset.position;
                track.infiniteClipOffsetEulerAngles = animAsset.eulerAngles;
                track.infiniteClipRemoveOffset      = animAsset.removeStartOffset;
                track.infiniteClipApplyFootIK       = animAsset.applyFootIK;
                track.infiniteClipLoop = animAsset.loop;
            }

            // clone it, it may not be in the same asset
            var animClip = clip.animationClip;

            float scale = (float)clip.timeScale;

            if (!Mathf.Approximately(scale, 1.0f))
            {
                if (!Mathf.Approximately(scale, 0.0f))
                {
                    scale = 1.0f / scale;
                }
                animClip.ScaleTime(scale);
            }

            TimelineUndo.PushUndo(animClip, L10n.Tr("Convert From Clip"));
            animClip.ShiftBySeconds(delta);

            // manually delete the clip
            var asset = clip.asset;

            clip.asset = null;

            // Remove the clip, remove old assets
            ClipModifier.Delete(timeline, clip);
            TimelineUndo.PushDestroyUndo(null, track, asset);

            track.infiniteClip = animClip;

            EditorUtility.SetDirty(track);
        }
        static void AddMarkerToParent(ScriptableObject marker, TrackAsset parent)
        {
            TimelineCreateUtilities.SaveAssetIntoObject(marker, parent);
            TimelineUndo.RegisterCreatedObjectUndo(marker, L10n.Tr("Duplicate Marker"));
            UndoExtensions.RegisterTrack(parent, L10n.Tr("Duplicate Marker"));

            if (parent != null)
            {
                parent.AddMarker(marker);
                ((IMarker)marker).Initialize(parent);
            }
        }
        internal static void ConvertToClipMode(this AnimationTrack track)
        {
            if (!track.CanConvertToClipMode())
            {
                return;
            }

            UndoExtensions.RegisterTrack(track, L10n.Tr("Convert To Clip"));

            if (!track.infiniteClip.empty)
            {
                var animClip = track.infiniteClip;
                TimelineUndo.PushUndo(animClip, L10n.Tr("Convert To Clip"));
                UndoExtensions.RegisterTrack(track, L10n.Tr("Convert To Clip"));
                var start = AnimationClipCurveCache.Instance.GetCurveInfo(animClip).keyTimes.FirstOrDefault();
                animClip.ShiftBySeconds(-start);

                track.infiniteClip = null;
                var clip = track.CreateClip(animClip);

                clip.start = start;
                clip.preExtrapolationMode  = track.infiniteClipPreExtrapolation;
                clip.postExtrapolationMode = track.infiniteClipPostExtrapolation;
                clip.recordable            = true;
                if (Mathf.Abs(animClip.length) < TimelineClip.kMinDuration)
                {
                    clip.duration = 1;
                }

                var animationAsset = clip.asset as AnimationPlayableAsset;
                if (animationAsset)
                {
                    animationAsset.position    = track.infiniteClipOffsetPosition;
                    animationAsset.eulerAngles = track.infiniteClipOffsetEulerAngles;

                    // going to / from infinite mode should reset this. infinite mode
                    animationAsset.removeStartOffset = track.infiniteClipRemoveOffset;
                    animationAsset.applyFootIK       = track.infiniteClipApplyFootIK;
                    animationAsset.loop = track.infiniteClipLoop;

                    track.infiniteClipOffsetPosition    = Vector3.zero;
                    track.infiniteClipOffsetEulerAngles = Vector3.zero;
                }

                track.CalculateExtrapolationTimes();
            }

            track.infiniteClip = null;

            EditorUtility.SetDirty(track);
        }
Пример #7
0
        public static void BeginTrim(ITimelineItem item, TrimEdge trimDirection)
        {
            var itemToTrim = item as ITrimmable;

            if (itemToTrim == null)
            {
                return;
            }

            s_CurrentTrimItem      = itemToTrim;
            s_CurrentTrimDirection = trimDirection;
            trimMode.OnBeforeTrim(itemToTrim, trimDirection);
            UndoExtensions.RegisterTrack(itemToTrim.parentTrack, L10n.Tr("Trim Clip"));
        }
        private void ConvertToRecordableClip(AnimationTrack track)
        {
            if (track == null || !track.hasClips)
            {
                return;
            }

            UndoExtensions.RegisterTrack(track, L10n.Tr("ConvertToRecordableClip"));

            var clip     = track.GetClips().First();
            var delta    = (float)clip.start;
            var duration = clip.duration;

            var animationAsset = clip.asset as AnimationPlayableAsset;

            if (animationAsset == null)
            {
                return;
            }
            var animationClipSource = animationAsset.clip;
            var animationName       = animationClipSource.name;

            foreach (var c in track.GetClips())
            {
                track.DeleteClip(c);
            }

            var recordableClip = track.CreateRecordableClip(animationName);

            recordableClip.start    = delta;
            recordableClip.duration = duration;
            var newAnimationClip = (recordableClip.asset as AnimationPlayableAsset).clip;


            newAnimationClip.name = animationName;
            var setting = AnimationUtility.GetAnimationClipSettings(animationClipSource);

            AnimationUtility.SetAnimationClipSettings(newAnimationClip, setting);
            newAnimationClip.frameRate = animationClipSource.frameRate;
            EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(animationClipSource);
            for (int i = 0; i < curveBindings.Length; i++)
            {
                AnimationUtility.SetEditorCurve(newAnimationClip, curveBindings[i],
                                                AnimationUtility.GetEditorCurve(animationClipSource, curveBindings[i]));
            }


            EditorUtility.SetDirty(track);
        }
        // Special method to remove a track that is in a broken state. i.e. the script won't load
        internal static bool RemoveBrokenTrack(PlayableAsset parent, ScriptableObject track)
        {
            var parentTrack    = parent as TrackAsset;
            var parentTimeline = parent as TimelineAsset;

            if (parentTrack == null && parentTimeline == null)
            {
                throw new ArgumentException("parent is not a valid parent type", "parent");
            }

            // this object must be a Unity null, but not actually null;
            object trackAsObject = track;

            if (trackAsObject == null || track as TrackAsset != null) // yes, this is correct
            {
                throw new ArgumentException("track is not in a broken state");
            }

            // this belongs to a parent track
            if (parentTrack != null)
            {
                int index = parentTrack.subTracksObjects.FindIndex(t => t.GetInstanceID() == track.GetInstanceID());
                if (index >= 0)
                {
                    UndoExtensions.RegisterTrack(parentTrack, L10n.Tr("Remove Track"));
                    parentTrack.subTracksObjects.RemoveAt(index);
                    parentTrack.Invalidate();
                    Undo.DestroyObjectImmediate(track);
                    return(true);
                }
            }
            else if (parentTimeline != null)
            {
                int index = parentTimeline.trackObjects.FindIndex(t => t.GetInstanceID() == track.GetInstanceID());
                if (index >= 0)
                {
                    UndoExtensions.RegisterPlayableAsset(parentTimeline, L10n.Tr("Remove Track"));
                    parentTimeline.trackObjects.RemoveAt(index);
                    parentTimeline.Invalidate();
                    Undo.DestroyObjectImmediate(track);
                    return(true);
                }
            }

            return(false);
        }
        void DoOffsetManipulator()
        {
            if (targets.Length > 1) //do not edit the track offset on a multiple selection
            {
                return;
            }

            if (timelineWindow == null || timelineWindow.state == null || timelineWindow.state.editSequence.director == null)
            {
                return;
            }

            AnimationTrack animationTrack = target as AnimationTrack;

            if (animationTrack != null && (animationTrack.trackOffset == TrackOffset.ApplyTransformOffsets) && m_OffsetEditMode != TimelineAnimationUtilities.OffsetEditMode.None)
            {
                var boundObject          = TimelineUtility.GetSceneGameObject(timelineWindow.state.editSequence.director, animationTrack);
                var boundObjectTransform = boundObject != null ? boundObject.transform : null;

                var offsets = TimelineAnimationUtilities.GetTrackOffsets(animationTrack, boundObjectTransform);
                EditorGUI.BeginChangeCheck();

                switch (m_OffsetEditMode)
                {
                case TimelineAnimationUtilities.OffsetEditMode.Translation:
                    offsets.position = Handles.PositionHandle(offsets.position, (Tools.pivotRotation == PivotRotation.Global)
                            ? Quaternion.identity
                            : offsets.rotation);
                    break;

                case TimelineAnimationUtilities.OffsetEditMode.Rotation:
                    offsets.rotation = Handles.RotationHandle(offsets.rotation, offsets.position);
                    break;
                }

                if (EditorGUI.EndChangeCheck())
                {
                    UndoExtensions.RegisterTrack(animationTrack, L10n.Tr("Inspector"));
                    TimelineAnimationUtilities.UpdateTrackOffset(animationTrack, boundObjectTransform, offsets);
                    Evaluate();
                    Repaint();
                }
            }
        }
Пример #11
0
        public void HandleTrackSwitch(IEnumerable <ItemsPerTrack> itemsGroups)
        {
            foreach (var itemsGroup in itemsGroups)
            {
                var targetTrack = itemsGroup.targetTrack;
                if (targetTrack != null && itemsGroup.items.Any())
                {
                    var compatible = itemsGroup.items.First().IsCompatibleWithTrack(targetTrack) &&
                                     !EditModeUtils.IsInfiniteTrack(targetTrack);
                    var track = compatible ? targetTrack : null;

                    UndoExtensions.RegisterTrack(track, L10n.Tr("Move Items"));
                    EditModeUtils.SetParentTrack(itemsGroup.items, track);
                }
                else
                {
                    EditModeUtils.SetParentTrack(itemsGroup.items, null);
                }
            }
        }
Пример #12
0
        public AnimationClip PrepareTrack(TrackAsset track, WindowState state, GameObject gameObject, out double startTime)
        {
            AnimationClip animationClip = null;

            // if we are not in clip mode, we simply use the track clip
            var animationTrack = (AnimationTrack)track;

            // ignore recording if we are in Legacy auto mode
            startTime = -1;
            var parentTrack = TimelineUtility.GetSceneReferenceTrack(track) as AnimationTrack;

            if (parentTrack != null && parentTrack.trackOffset == TrackOffset.Auto)
            {
                return(null);
            }

            if (!animationTrack.inClipMode)
            {
                var trackClip = animationTrack.GetOrCreateClip();
                startTime = trackClip.frameRate * state.editSequence.time;

                // Make the first key be at time 0 of the clip
                if (trackClip.empty)
                {
                    animationTrack.infiniteClipTimeOffset        = 0; // state.time;
                    animationTrack.infiniteClipPreExtrapolation  = TimelineClip.ClipExtrapolation.Hold;
                    animationTrack.infiniteClipPostExtrapolation = TimelineClip.ClipExtrapolation.Hold;
                }

                animationClip = trackClip;
            }
            else
            {
                TimelineClip activeClip = null;

                // if it fails, but returns no clip, we can add one.
                if (!track.FindRecordingClipAtTime(state.editSequence.time, out activeClip) && activeClip != null)
                {
                    return(null);
                }

                if (activeClip == null)
                {
                    activeClip = AddRecordableClip(track, state, state.editSequence.time);
                }

                var clip = activeClip.animationClip;

                // flags this as the clip being recorded for the track
                var clipTime = state.editSequence.time - activeClip.start;

                // if we are in the past
                if (clipTime < 0)
                {
                    Undo.RegisterCompleteObjectUndo(clip, "Record Key");
                    UndoExtensions.RegisterTrack(track, "Prepend Key");
                    ShiftAnimationClip(clip, (float)-clipTime);
                    activeClip.start     = state.editSequence.time;
                    activeClip.duration += -clipTime;
                    clipTime             = 0;
                }

                m_ClipTime         = clipTime;
                recordClip         = activeClip;
                startTime          = recordClip.ToLocalTimeUnbound(state.editSequence.time) * clip.frameRate;
                m_needRebuildRects = clip.empty;

                animationClip = clip;
            }

            m_TargetClip = animationClip;
            m_CurveCount = GetCurveCount(animationClip);
            m_TrackHasPreviewComponents = animationTrack.hasPreviewComponents;

            return(animationClip);
        }