UnityGame/Library/PackageCache/com.unity.timeline/Editor/Window/TimelineWindowTimeControl.cs
2024-10-27 10:53:47 +03:00

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);
}
}
}