323 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using UnityEditorInternal;
 | |
| using UnityEngine;
 | |
| using UnityEngine.Timeline;
 | |
| using Object = UnityEngine.Object;
 | |
| 
 | |
| namespace UnityEditor.Timeline
 | |
| {
 | |
|     class TimelineWindowTimeControl : IAnimationWindowControl
 | |
|     {
 | |
|         [Serializable]
 | |
|         public struct ClipData
 | |
|         {
 | |
|             public double start;
 | |
|             public double duration;
 | |
|             public TrackAsset track;
 | |
|         }
 | |
| 
 | |
| #if UNITY_2021_2_OR_NEWER
 | |
|         const AnimationWindowState.SnapMode k_SnapMode = AnimationWindowState.SnapMode.SnapToFrame;
 | |
| #else
 | |
|         const AnimationWindowState.SnapMode k_SnapMode = AnimationWindowState.SnapMode.SnapToClipFrame;
 | |
| #endif
 | |
| 
 | |
|         [SerializeField] ClipData m_ClipData;
 | |
|         [SerializeField] TimelineClip m_Clip;
 | |
|         [SerializeField] AnimationWindowState m_AnimWindowState;
 | |
| 
 | |
|         TrackAsset track
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (m_Clip != null)
 | |
|                 {
 | |
|                     return m_Clip.GetParentTrack();
 | |
|                 }
 | |
|                 return m_ClipData.track;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static TimelineWindow window
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return TimelineWindow.instance;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static WindowState state
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (window != null)
 | |
|                     return window.state;
 | |
|                 return null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void OnStateChange()
 | |
|         {
 | |
|             if (m_AnimWindowState != null)
 | |
|                 m_AnimWindowState.Repaint();
 | |
|         }
 | |
| 
 | |
|         public void Init(AnimationWindowState animState, TimelineClip clip)
 | |
|         {
 | |
|             m_Clip = clip;
 | |
|             m_AnimWindowState = animState;
 | |
|         }
 | |
| 
 | |
|         public void Init(AnimationWindowState animState, ClipData clip)
 | |
|         {
 | |
|             m_ClipData = clip;
 | |
|             m_AnimWindowState = animState;
 | |
|         }
 | |
| 
 | |
|         public override void OnEnable()
 | |
|         {
 | |
|             if (state != null)
 | |
|                 state.OnTimeChange += OnStateChange;
 | |
| 
 | |
|             base.OnEnable();
 | |
|         }
 | |
| 
 | |
|         public void OnDisable()
 | |
|         {
 | |
|             if (state != null)
 | |
|                 state.OnTimeChange -= OnStateChange;
 | |
|         }
 | |
| 
 | |
|         public override AnimationKeyTime time
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (state == null)
 | |
|                     return AnimationKeyTime.Time(0.0f, 0.0f);
 | |
| 
 | |
|                 return AnimationKeyTime.Time(ToAnimationClipTime(state.editSequence.time), (float)state.referenceSequence.frameRate);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void ChangeTime(double newTime)
 | |
|         {
 | |
|             if (state != null && state.editSequence.director != null)
 | |
|             {
 | |
|                 // avoid rounding errors
 | |
|                 var finalTime = ToGlobalTime(newTime);
 | |
|                 if (TimeUtility.OnFrameBoundary(finalTime, state.referenceSequence.frameRate, TimeUtility.kFrameRateEpsilon))
 | |
|                     finalTime = TimeUtility.RoundToFrame(finalTime, state.referenceSequence.frameRate);
 | |
|                 state.editSequence.time = finalTime;
 | |
| 
 | |
|                 window.Repaint();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void ChangeFrame(int frame)
 | |
|         {
 | |
|             frame = Math.Max(0, frame);
 | |
| 
 | |
|             if (state != null && state.referenceSequence != null)
 | |
|             {
 | |
|                 double frameTime = TimeUtility.FromFrames(frame, state.referenceSequence.frameRate);
 | |
|                 ChangeTime(frameTime);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public override void GoToTime(float newTime)
 | |
|         {
 | |
|             ChangeTime(newTime);
 | |
|         }
 | |
| 
 | |
|         public override void GoToFrame(int frame)
 | |
|         {
 | |
|             ChangeFrame(frame);
 | |
|         }
 | |
| 
 | |
|         public override void StartScrubTime() { }
 | |
| 
 | |
|         public override void EndScrubTime() { }
 | |
| 
 | |
|         public override void ScrubTime(float newTime)
 | |
|         {
 | |
|             ChangeTime(newTime);
 | |
|         }
 | |
| 
 | |
|         public override void GoToPreviousFrame()
 | |
|         {
 | |
|             if (state != null)
 | |
|                 ChangeFrame(state.editSequence.frame - 1);
 | |
|         }
 | |
| 
 | |
|         public override void GoToNextFrame()
 | |
|         {
 | |
|             if (state != null)
 | |
|                 ChangeFrame(state.editSequence.frame + 1);
 | |
|         }
 | |
| 
 | |
|         AnimationWindowCurve[] GetCurves()
 | |
|         {
 | |
|             var curves =
 | |
|                 (m_AnimWindowState.showCurveEditor &&
 | |
|                     m_AnimWindowState.activeCurves.Count > 0) ? m_AnimWindowState.activeCurves : m_AnimWindowState.allCurves;
 | |
|             return curves.ToArray();
 | |
|         }
 | |
| 
 | |
|         public override void GoToPreviousKeyframe()
 | |
|         {
 | |
|             var newTime = AnimationWindowUtility.GetPreviousKeyframeTime(GetCurves(), time.time, m_AnimWindowState.clipFrameRate);
 | |
|             GoToTime(m_AnimWindowState.SnapToFrame(newTime, k_SnapMode));
 | |
|         }
 | |
| 
 | |
|         public override void GoToNextKeyframe()
 | |
|         {
 | |
|             var newTime = AnimationWindowUtility.GetNextKeyframeTime(GetCurves(), time.time, m_AnimWindowState.clipFrameRate);
 | |
|             GoToTime(m_AnimWindowState.SnapToFrame(newTime, k_SnapMode));
 | |
|         }
 | |
| 
 | |
|         public override void GoToFirstKeyframe()
 | |
|         {
 | |
|             GoToTime(0);
 | |
|         }
 | |
| 
 | |
|         public override void GoToLastKeyframe()
 | |
|         {
 | |
|             double animClipTime = 0;
 | |
|             if (m_Clip != null)
 | |
|             {
 | |
|                 var curves = m_Clip.curves;
 | |
|                 var animAsset = m_Clip.asset as AnimationPlayableAsset;
 | |
|                 if (animAsset != null)
 | |
|                 {
 | |
|                     animClipTime = animAsset.clip != null ? animAsset.clip.length : 0;
 | |
|                 }
 | |
|                 else if (curves != null)
 | |
|                 {
 | |
|                     animClipTime = curves.length;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     animClipTime = m_Clip.clipAssetDuration;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 animClipTime = m_ClipData.duration;
 | |
|             }
 | |
| 
 | |
|             GoToTime((float)animClipTime);
 | |
|         }
 | |
| 
 | |
|         public override bool canPlay
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return state != null && state.previewMode;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public override bool playing
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return state != null && state.playing;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         static void SetPlaybackState(bool playbackState)
 | |
|         {
 | |
|             if (state == null || playbackState == state.playing)
 | |
|                 return;
 | |
| 
 | |
|             state.SetPlaying(playbackState);
 | |
|         }
 | |
| 
 | |
|         public override bool StartPlayback()
 | |
|         {
 | |
|             SetPlaybackState(true);
 | |
|             return state != null && state.playing;
 | |
|         }
 | |
| 
 | |
|         public override void StopPlayback()
 | |
|         {
 | |
|             SetPlaybackState(false);
 | |
|         }
 | |
| 
 | |
|         public override bool PlaybackUpdate() { return state != null && state.playing; }
 | |
| 
 | |
|         public override bool canRecord
 | |
|         {
 | |
|             get { return state != null && state.canRecord; }
 | |
|         }
 | |
| 
 | |
|         public override bool recording
 | |
|         {
 | |
|             get { return state != null && state.recording; }
 | |
|         }
 | |
| 
 | |
|         public override bool canPreview
 | |
|         {
 | |
|             get { return false; }
 | |
|         }
 | |
| 
 | |
|         public override bool previewing
 | |
|         {
 | |
|             get { return true; }
 | |
|         }
 | |
| 
 | |
|         public override bool StartRecording(Object targetObject)
 | |
|         {
 | |
|             if (!canRecord)
 | |
|                 return false;
 | |
| 
 | |
|             if (track != null && state != null && !state.ignorePreview)
 | |
|             {
 | |
|                 state.ArmForRecord(track);
 | |
|                 return state.recording;
 | |
|             }
 | |
| 
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         public override void StopRecording()
 | |
|         {
 | |
|             if (track != null && state != null && !state.ignorePreview)
 | |
|                 state.UnarmForRecord(track);
 | |
|         }
 | |
| 
 | |
|         public override void OnSelectionChanged() { }
 | |
| 
 | |
|         public override void ResampleAnimation() { }
 | |
| 
 | |
|         public override bool StartPreview()
 | |
|         {
 | |
|             if (state != null)
 | |
|                 state.previewMode = true;
 | |
|             return state != null && state.previewMode;
 | |
|         }
 | |
| 
 | |
|         public override void StopPreview()
 | |
|         {
 | |
|             if (state != null)
 | |
|                 state.previewMode = false;
 | |
|         }
 | |
| 
 | |
|         public override void ProcessCandidates() { }
 | |
|         public override void ClearCandidates() { }
 | |
| 
 | |
|         double ToGlobalTime(double localTime)
 | |
|         {
 | |
|             if (m_Clip != null)
 | |
|                 return Math.Max(0, m_Clip.FromLocalTimeUnbound(localTime));
 | |
|             return Math.Max(0, m_ClipData.start + localTime);
 | |
|         }
 | |
| 
 | |
|         float ToAnimationClipTime(double globalTime)
 | |
|         {
 | |
|             if (m_Clip != null)
 | |
|                 return (float)m_Clip.ToLocalTimeUnbound(globalTime);
 | |
|             return (float)(globalTime - m_ClipData.start);
 | |
|         }
 | |
|     }
 | |
| }
 |