예제 #1
0
        // Gets the appropriate track for a given game object
        static TrackAsset GetTrackForGameObject(GameObject gameObject, WindowState state)
        {
            if (gameObject == null)
            {
                return(null);
            }

            var director = state.editSequence.director;

            if (director == null)
            {
                return(null);
            }

            var level = int.MaxValue;

            TrackAsset result = null;

            // search the output tracks
            var outputTracks = state.editSequence.asset.flattenedTracks;

            foreach (var track in outputTracks)
            {
                if (track.GetType() != typeof(AnimationTrack))
                {
                    continue;
                }
                if (!state.IsArmedForRecord(track))
                {
                    continue;
                }

                var obj = TimelineUtility.GetSceneGameObject(director, track);
                if (obj != null)
                {
                    // checks if the effected gameobject is our child
                    var childLevel = GetChildLevel(obj, gameObject);
                    if (childLevel != -1 && childLevel < level)
                    {
                        result = track;
                        level  = childLevel;
                    }
                }
            }

            // the resulting track is not armed. checking here avoids accidentally recording objects with their own
            // tracks
            if (result && !state.IsArmedForRecord(result))
            {
                result = null;
            }

            return(result);
        }
        public bool CanDraw(TrackAsset track, WindowState state)
        {
            var keys         = m_DataSource.GetKeys();
            var isTrackEmpty = track.clips.Length == 0;

            return(keys != null || (state.IsArmedForRecord(track) && isTrackEmpty));
        }
        static bool CanExecute(WindowState state, ActionContext context)
        {
            if (context.timeline == null)
            {
                return(false);
            }

            if (context.markers.Any())
            {
                return(false);
            }

            if (context.tracks.ContainsTimelineMarkerTrack(context.timeline))
            {
                return(false);
            }

            IClipCurveEditorOwner curveSelected = SelectionManager.GetCurrentInlineEditorCurve();

            // Can't have an inline curve selected and have multiple tracks also.
            if (curveSelected != null)
            {
                return(state.IsArmedForRecord(curveSelected.owner));
            }

            return(GetKeyableTracks(state, context).Any());
        }
예제 #4
0
        public override bool DrawTrack(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
        {
            m_TrackRect = trackRect;

            if (!CanDraw(trackAsset, state))
            {
                return(true);
            }

            if (state.recording && state.IsArmedForRecord(trackAsset))
            {
                DrawRecordBackground(trackRect);
            }

            GUI.Box(trackRect, GUIContent.none, DirectorStyles.Instance.infiniteTrack);

            var shadowRect = trackRect;

            shadowRect.yMin   = shadowRect.yMax;
            shadowRect.height = 15.0f;
            GUI.DrawTexture(shadowRect, DirectorStyles.Instance.bottomShadow.normal.background, ScaleMode.StretchToFill);

            var keys = m_DataSource.GetKeys();

            if (keys != null && keys.Length > 0)
            {
                foreach (var k in keys)
                {
                    DrawKeyFrame(k, state);
                }
            }

            return(true);
        }
예제 #5
0
        public static IEnumerable <GameObject> GetRecordableGameObjects(WindowState state)
        {
            if (state == null || state.editSequence.asset == null || state.editSequence.director == null)
            {
                yield break;
            }

            var outputTracks = state.editSequence.asset.GetOutputTracks();

            foreach (var track in outputTracks)
            {
                if (track.GetType() != typeof(AnimationTrack))
                {
                    continue;
                }
                if (!state.IsArmedForRecord(track) && !track.GetChildTracks().Any(state.IsArmedForRecord))
                {
                    continue;
                }

                var obj = TimelineUtility.GetSceneGameObject(state.editSequence.director, track);
                if (obj != null)
                {
                    yield return(obj);
                }
            }
        }
예제 #6
0
        bool ShouldShowClipCurves(WindowState state)
        {
            if (m_TrackGUI.clips.Count == 0)
            {
                return(false);
            }

            // Is a clip selected or being recorded to?
            return(SelectionManager.SelectedClipGUI().FirstOrDefault(x => x.parent == m_TrackGUI) != null ||
                   state.recording && state.IsArmedForRecord(m_TrackGUI.track) && m_TrackGUI.clips.FirstOrDefault(x => m_TrackGUI.track.IsRecordingToClip(x.clip)) != null);
        }
예제 #7
0
        static void DrawBorderOfAddedRecordingClip(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
        {
            if (!state.IsArmedForRecord(trackAsset))
            {
                return;
            }

            AnimationTrack animTrack = trackAsset as AnimationTrack;

            if (animTrack == null || !animTrack.inClipMode)
            {
                return;
            }

            // make sure there is no clip but we can add one
            TimelineClip clip = null;

            if (trackAsset.FindRecordingClipAtTime(state.editSequence.time, out clip) || clip != null)
            {
                return;
            }

            float yMax = trackRect.yMax;
            float yMin = trackRect.yMin;

            double startGap = 0;
            double endGap   = 0;

            trackAsset.GetGapAtTime(state.editSequence.time, out startGap, out endGap);
            if (double.IsInfinity(endGap))
            {
                endGap = visibleTime.y;
            }

            if (startGap > visibleTime.y || endGap < visibleTime.x)
            {
                return;
            }


            startGap = Math.Max(startGap, visibleTime.x);
            endGap   = Math.Min(endGap, visibleTime.y);

            float xMin = state.TimeToPixel(startGap);
            float xMax = state.TimeToPixel(endGap);

            Rect r = Rect.MinMaxRect(xMin, yMin, xMax, yMax);

            ClipDrawer.DrawBorder(r, ClipBorder.kRecording, ClipBlends.kNone);
        }
예제 #8
0
        // Helper that finds the animation clip we are recording and the relative time to that clip
        static bool GetClipAndRelativeTime(UnityEngine.Object target, WindowState state,
                                           out AnimationClip outClip, out double keyTime, out bool keyInRange)
        {
            const float floatToDoubleError = 0.00001f;

            outClip    = null;
            keyTime    = 0;
            keyInRange = false;

            double        startTime = 0;
            double        timeScale = 1;
            AnimationClip clip      = null;

            IPlayableAsset playableAsset = target as IPlayableAsset;
            Component      component     = target as Component;

            // Handle recordable playable assets
            if (playableAsset != null)
            {
                var timelineClip = FindClipWithAsset(state.editSequence.asset, playableAsset, state.editSequence.director);
                if (timelineClip != null && state.IsArmedForRecord(timelineClip.parentTrack))
                {
                    AnimatedParameterExtensions.CreateCurvesIfRequired(timelineClip);
                    clip      = timelineClip.curves;
                    startTime = timelineClip.start;
                    timeScale = timelineClip.timeScale;
                }
            }
            // Handle recording components, including infinite clip
            else if (component != null)
            {
                var asset = GetTrackForGameObject(component.gameObject, state);
                if (asset != null)
                {
                    clip = GetRecordingClip(asset, state, out startTime, out timeScale);
                }
            }

            if (clip == null)
            {
                return(false);
            }

            keyTime    = (state.editSequence.time - startTime) * timeScale;
            outClip    = clip;
            keyInRange = keyTime >= 0 && keyTime <= (clip.length * timeScale + floatToDoubleError);

            return(true);
        }
예제 #9
0
        void DrawCurveEditorsForClipsOnTrack(Rect headerRect, Rect trackRect, WindowState state)
        {
            if (m_TrackGUI.clips.Count == 0)
            {
                return;
            }

            if (Event.current.type == EventType.Layout)
            {
                var selectedClip = SelectionManager.SelectedClipGUI().FirstOrDefault(x => x.parent == m_TrackGUI);
                if (selectedClip != null)
                {
                    m_LastSelectedClipGUI = selectedClip;
                    SelectFromCurveOwner(m_LastSelectedClipGUI);
                }
                else if (state.recording && state.IsArmedForRecord(m_TrackGUI.track))
                {
                    if (m_LastSelectedClipGUI == null || !m_TrackGUI.track.IsRecordingToClip(m_LastSelectedClipGUI.clip))
                    {
                        var clip = m_TrackGUI.clips.FirstOrDefault(x => m_TrackGUI.track.IsRecordingToClip(x.clip));
                        if (clip != null)
                        {
                            m_LastSelectedClipGUI = clip;
                        }
                    }
                }

                if (m_LastSelectedClipGUI == null)
                {
                    m_LastSelectedClipGUI = m_TrackGUI.clips[0];
                }
            }

            if (m_LastSelectedClipGUI == null || m_LastSelectedClipGUI.clipCurveEditor == null || m_LastSelectedClipGUI.isInvalid)
            {
                return;
            }

            var activeRange = new Vector2(state.TimeToPixel(m_LastSelectedClipGUI.clip.start), state.TimeToPixel(m_LastSelectedClipGUI.clip.end));

            DrawCurveEditor(m_LastSelectedClipGUI, state, headerRect, trackRect, activeRange, m_TrackGUI.locked);
            m_LastSelectionWasClip = true;
        }
        public override bool DrawTrack(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
        {
            m_TrackRect = trackRect;

            if (!CanDraw(trackAsset, state))
            {
                return(true);
            }

            if (state.recording && state.IsArmedForRecord(trackAsset))
            {
                DrawRecordBackground(trackRect);
            }

            if (m_DataSource.GetKeys() != null && m_DataSource.GetKeys().Length > 0 || state.recording)
            {
                GUI.Box(trackRect, GUIContent.none, DirectorStyles.Instance.infiniteTrack);
            }

            var shadowRect = trackRect;

            shadowRect.yMin   = shadowRect.yMax;
            shadowRect.height = 15.0f;
            if (Event.current.type == EventType.Repaint)
            {
                DirectorStyles.Instance.bottomShadow.Draw(shadowRect, false, false, false, false);
            }

            var keys = m_DataSource.GetKeys();

            if (keys != null && keys.Length > 0)
            {
                foreach (var k in keys)
                {
                    DrawKeyFrame(k, state);
                }
            }

            return(true);
        }
예제 #11
0
 bool IsRecording(WindowState state)
 {
     return(state.recording && state.IsArmedForRecord(track));
 }
 internal static bool IsRecording(TimelineClip clip, WindowState state)
 {
     return(clip != null &&
            clip.parentTrack != null &&
            state.IsArmedForRecord(clip.parentTrack));
 }