|
|
using System;using System.Collections.Generic;using System.Linq;using UnityEditor.Experimental.SceneManagement;using UnityEngine.Experimental.Animations;using UnityEditorInternal;using UnityEngine;using UnityEngine.Playables;using UnityEngine.Timeline;using UnityEngine.Animations;
namespace UnityEditor.Timeline{ delegate bool PendingUpdateDelegate(WindowState state, Event currentEvent);
class WindowState { const int k_TimeCodeTextFieldId = 3790;
readonly TimelineWindow m_Window; bool m_Recording; readonly SpacePartitioner m_SpacePartitioner = new SpacePartitioner(); readonly List<Manipulator> m_CaptureSession = new List<Manipulator>(); int m_DirtyStamp; float m_SequencerHeaderWidth = WindowConstants.defaultHeaderWidth; float m_BindingAreaWidth = WindowConstants.defaultBindingAreaWidth;
bool m_MustRebuildGraph;
float m_LastTime;
readonly PropertyCollector m_PropertyCollector = new PropertyCollector();
static AnimationModeDriver s_PreviewDriver; List<Animator> m_PreviewedAnimators; List<IAnimationWindowPreview> m_PreviewedComponents;
public static double kTimeEpsilon { get { return TimeUtility.kTimeEpsilon; } } public static readonly float kMaxShownTime = (float)TimeUtility.k_MaxTimelineDurationInSeconds;
static readonly ISequenceState k_NullSequenceState = new NullSequenceState();
// which tracks are armed for record - only one allowed per 'actor'
Dictionary<TrackAsset, TrackAsset> m_ArmedTracks = new Dictionary<TrackAsset, TrackAsset>();
TimelineWindow.TimelineWindowPreferences m_Preferences;
List<PendingUpdateDelegate> m_OnStartFrameUpdates; List<PendingUpdateDelegate> m_OnEndFrameUpdates;
readonly SequenceHierarchy m_SequenceHierarchy;
public event Action<WindowState, Event> windowOnGuiStarted; public event Action<WindowState, Event> windowOnGuiFinished;
public event Action<bool> OnPlayStateChange; public event Action OnDirtyStampChange; public event Action OnRebuildGraphChange; public event Action OnTimeChange; public event Action OnRecordingChange;
public event Action OnBeforeSequenceChange; public event Action OnAfterSequenceChange;
public WindowState(TimelineWindow w, SequenceHierarchy hierarchy) { m_Window = w; m_Preferences = w.preferences; hierarchy.Init(this); m_SequenceHierarchy = hierarchy; TimelinePlayable.muteAudioScrubbing = muteAudioScrubbing; }
public static AnimationModeDriver previewDriver { get { if (s_PreviewDriver == null) s_PreviewDriver = ScriptableObject.CreateInstance<AnimationModeDriver>(); return s_PreviewDriver; } }
public EditorWindow editorWindow { get { return m_Window; } }
public ISequenceState editSequence { get { // Using "null" ISequenceState to avoid checking against null all the time.
// This *should* be removed in a phase 2 of refactoring, where we make sure
// to pass around the correct state object instead of letting clients dig
// into the WindowState for whatever they want.
return m_SequenceHierarchy.editSequence ?? k_NullSequenceState; } }
public ISequenceState masterSequence { get { return m_SequenceHierarchy.masterSequence ?? k_NullSequenceState; } }
public ISequenceState referenceSequence { get { return timeReferenceMode == TimeReferenceMode.Local ? editSequence : masterSequence; } }
public bool rebuildGraph { get { return m_MustRebuildGraph; } set { SyncNotifyValue(ref m_MustRebuildGraph, value, OnRebuildGraphChange); } }
public float mouseDragLag { get; set; }
public SpacePartitioner spacePartitioner { get { return m_SpacePartitioner; } }
public List<Manipulator> captured { get { return m_CaptureSession; } }
public void AddCaptured(Manipulator manipulator) { if (!m_CaptureSession.Contains(manipulator)) m_CaptureSession.Add(manipulator); }
public void RemoveCaptured(Manipulator manipulator) { m_CaptureSession.Remove(manipulator); }
public bool isJogging { get; set; }
public int viewStateHash { get; private set; }
public float bindingAreaWidth { get { return m_BindingAreaWidth; } set { m_BindingAreaWidth = value; } }
public float sequencerHeaderWidth { get { return m_SequencerHeaderWidth; } set { m_SequencerHeaderWidth = Mathf.Clamp(value, WindowConstants.minHeaderWidth, WindowConstants.maxHeaderWidth); } }
public float mainAreaWidth { get; set; }
public float trackScale { get { return editSequence.viewModel.trackScale; } set { editSequence.viewModel.trackScale = value; m_Window.treeView.CalculateRowRects(); } }
public int dirtyStamp { get { return m_DirtyStamp; } private set { SyncNotifyValue(ref m_DirtyStamp, value, OnDirtyStampChange); } }
public bool showQuadTree { get; set; }
public bool canRecord { get { return AnimationMode.InAnimationMode(previewDriver) || !AnimationMode.InAnimationMode(); } }
public bool recording { get { if (!previewMode) m_Recording = false; return m_Recording; } // set can only be used to disable recording
set { // force preview mode on
if (value) previewMode = true;
bool newValue = value; if (!previewMode) newValue = false;
if (newValue && m_ArmedTracks.Count == 0) { Debug.LogError("Cannot enable recording without an armed track"); newValue = false; }
if (!newValue) m_ArmedTracks.Clear();
if (newValue != m_Recording) { if (newValue) AnimationMode.StartAnimationRecording(); else AnimationMode.StopAnimationRecording();
InspectorWindow.RepaintAllInspectors(); }
SyncNotifyValue(ref m_Recording, newValue, OnRecordingChange); } }
public bool previewMode { get { return Application.isPlaying || AnimationMode.InAnimationMode(previewDriver); } set { if (Application.isPlaying) return; bool inAnimationMode = AnimationMode.InAnimationMode(previewDriver); if (!value) { if (inAnimationMode) { Stop();
OnStopPreview();
AnimationMode.StopAnimationMode(previewDriver);
AnimationPropertyContextualMenu.Instance.SetResponder(null); previewedDirectors = null; } } else if (!inAnimationMode) { editSequence.time = editSequence.viewModel.windowTime; EvaluateImmediate(); // does appropriate caching prior to enabling
} } }
public bool playing { get { return masterSequence.director != null && masterSequence.director.state == PlayState.Playing; } }
public float playbackSpeed { get; set; }
public bool frameSnap { get { return m_Preferences.frameSnap; } set { m_Preferences.frameSnap = value; } }
public bool edgeSnaps { get { return m_Preferences.edgeSnaps; } set { m_Preferences.edgeSnaps = value; } }
public bool muteAudioScrubbing { get { return m_Preferences.muteAudioScrub; } set { m_Preferences.muteAudioScrub = value; TimelinePlayable.muteAudioScrubbing = value; RebuildPlayableGraph(); } }
public bool playRangeLoopMode { get { return m_Preferences.playRangeLoopMode; } set { m_Preferences.playRangeLoopMode = value; } }
public TimeReferenceMode timeReferenceMode { get { return m_Preferences.timeReferenceMode; } set { m_Preferences.timeReferenceMode = value; } }
public bool timeInFrames { get { return editSequence.viewModel.timeInFrames; } set { editSequence.viewModel.timeInFrames = value; } }
public bool showAudioWaveform { get { return editSequence.viewModel.showAudioWaveform; } set { editSequence.viewModel.showAudioWaveform = value; } }
public Vector2 playRange { get { return masterSequence.viewModel.timeAreaPlayRange; } set { masterSequence.viewModel.timeAreaPlayRange = ValidatePlayRange(value); } }
public bool showMarkerHeader { get { return editSequence.viewModel.showMarkerHeader; } set { editSequence.viewModel.showMarkerHeader = value; } }
void UnSelectMarkerOnHeaderTrack() { //Where(m => editSequence.asset.markerTrack == m.parent)
foreach (IMarker marker in SelectionManager.SelectedMarkers()) { if (marker.parent == editSequence.asset.markerTrack) SelectionManager.Remove(marker); } }
public EditMode.EditType editType { get { return m_Preferences.editType; } set { m_Preferences.editType = value; } }
public PlaybackScrollMode autoScrollMode { get { return m_Preferences.autoScrollMode; } set { m_Preferences.autoScrollMode = value; } }
public bool isClipSnapping { get; set; }
public List<PlayableDirector> previewedDirectors { get; private set; }
public void OnDestroy() { if (!Application.isPlaying) Stop();
if (m_OnStartFrameUpdates != null) m_OnStartFrameUpdates.Clear();
if (m_OnEndFrameUpdates != null) m_OnEndFrameUpdates.Clear();
m_SequenceHierarchy.Clear(); windowOnGuiStarted = null; windowOnGuiFinished = null; }
public void OnSceneSaved() { // the director will reset it's time when the scene is saved.
EnsureWindowTimeConsistency(); }
public void SetCurrentSequence(TimelineAsset timelineAsset, PlayableDirector director, TimelineClip hostClip) { if (OnBeforeSequenceChange != null) OnBeforeSequenceChange.Invoke();
OnCurrentDirectorWillChange();
if (hostClip == null || timelineAsset == null) { m_PropertyCollector.Clear(); m_SequenceHierarchy.Clear(); }
if (timelineAsset != null) m_SequenceHierarchy.Add(timelineAsset, director, hostClip);
if (OnAfterSequenceChange != null) OnAfterSequenceChange.Invoke(); }
public void PopSequencesUntilCount(int count) { if (count >= m_SequenceHierarchy.count) return; if (count < 1) return;
if (OnBeforeSequenceChange != null) OnBeforeSequenceChange.Invoke();
var nextDirector = m_SequenceHierarchy.GetStateAtIndex(count - 1).director; OnCurrentDirectorWillChange();
m_SequenceHierarchy.RemoveUntilCount(count);
EnsureWindowTimeConsistency();
if (OnAfterSequenceChange != null) OnAfterSequenceChange.Invoke(); }
public SequencePath GetCurrentSequencePath() { return m_SequenceHierarchy.ToSequencePath(); }
public void SetCurrentSequencePath(SequencePath path, bool forceRebuild) { if (!m_SequenceHierarchy.NeedsUpdate(path, forceRebuild)) return;
if (OnBeforeSequenceChange != null) OnBeforeSequenceChange.Invoke();
m_SequenceHierarchy.FromSequencePath(path, forceRebuild);
if (OnAfterSequenceChange != null) OnAfterSequenceChange.Invoke(); }
public IEnumerable<ISequenceState> GetAllSequences() { return m_SequenceHierarchy.allSequences; }
public double SnapToFrameIfRequired(double currentTime) { return frameSnap ? TimeReferenceUtility.SnapToFrame(currentTime) : currentTime; }
public void Reset() { recording = false; previewMode = false; }
public double GetSnappedTimeAtMousePosition(Vector2 mousePos) { return SnapToFrameIfRequired(ScreenSpacePixelToTimeAreaTime(mousePos.x)); }
static void SyncNotifyValue<T>(ref T oldValue, T newValue, Action changeStateCallback) { var stateChanged = false;
if (oldValue == null) { oldValue = newValue; stateChanged = true; } else { if (!oldValue.Equals(newValue)) { oldValue = newValue; stateChanged = true; } }
if (stateChanged && changeStateCallback != null) { changeStateCallback.Invoke(); } }
public void SetTimeAreaTransform(Vector2 newTranslation, Vector2 newScale) { m_Window.timeArea.SetTransform(newTranslation, newScale); TimeAreaChanged(); }
public void SetTimeAreaShownRange(float min, float max) { m_Window.timeArea.SetShownHRange(min, max); TimeAreaChanged(); }
internal void TimeAreaChanged() { if (editSequence.asset != null) { Vector2 newShownRange = new Vector2(m_Window.timeArea.shownArea.x, m_Window.timeArea.shownArea.xMax); if (editSequence.viewModel.timeAreaShownRange != newShownRange) { editSequence.viewModel.timeAreaShownRange = newShownRange; if (!FileUtil.IsReadOnly(editSequence.asset)) EditorUtility.SetDirty(editSequence.asset); } } }
public void ResetPreviewMode() { var mode = previewMode; previewMode = false; previewMode = mode; }
public bool TimeIsInRange(float value) { Rect shownArea = m_Window.timeArea.shownArea; return value >= shownArea.x && value <= shownArea.xMax; }
public bool RangeIsVisible(Range range) { var shownArea = m_Window.timeArea.shownArea; return range.start < shownArea.xMax && range.end > shownArea.xMin; }
public void EnsurePlayHeadIsVisible() { double minDisplayedTime = PixelToTime(timeAreaRect.xMin); double maxDisplayedTime = PixelToTime(timeAreaRect.xMax);
double currentTime = editSequence.time; if (currentTime >= minDisplayedTime && currentTime <= maxDisplayedTime) return;
float displayedTimeRange = (float)(maxDisplayedTime - minDisplayedTime); float minimumTimeToDisplay = (float)currentTime - displayedTimeRange / 2.0f; float maximumTimeToDisplay = (float)currentTime + displayedTimeRange / 2.0f; SetTimeAreaShownRange(minimumTimeToDisplay, maximumTimeToDisplay); }
public void SetPlayHeadToMiddle() { double minDisplayedTime = PixelToTime(timeAreaRect.xMin); double maxDisplayedTime = PixelToTime(timeAreaRect.xMax);
double currentTime = editSequence.time; float displayedTimeRange = (float)(maxDisplayedTime - minDisplayedTime);
if (currentTime >= minDisplayedTime && currentTime <= maxDisplayedTime) { if (currentTime < minDisplayedTime + displayedTimeRange / 2) return; }
const float kCatchUpSpeed = 3f; float realDelta = Mathf.Clamp(Time.realtimeSinceStartup - m_LastTime, 0f, 1f) * kCatchUpSpeed; float scrollCatchupAmount = kCatchUpSpeed * realDelta * displayedTimeRange / 2;
if (currentTime < minDisplayedTime) { SetTimeAreaShownRange((float)currentTime, (float)currentTime + displayedTimeRange); } else if (currentTime > maxDisplayedTime) { SetTimeAreaShownRange((float)currentTime - displayedTimeRange + scrollCatchupAmount, (float)currentTime + scrollCatchupAmount); } else if (currentTime > minDisplayedTime + displayedTimeRange / 2) { float targetMinDisplayedTime = Mathf.Min((float)minDisplayedTime + scrollCatchupAmount, (float)(currentTime - displayedTimeRange / 2)); SetTimeAreaShownRange(targetMinDisplayedTime, targetMinDisplayedTime + displayedTimeRange); } }
internal void UpdateLastFrameTime() { m_LastTime = Time.realtimeSinceStartup; }
public Vector2 timeAreaShownRange { get { if (m_Window.state.editSequence.asset != null) return editSequence.viewModel.timeAreaShownRange;
return TimelineAssetViewModel.TimeAreaDefaultRange; } }
public Vector2 timeAreaTranslation { get { return m_Window.timeArea.translation; } }
public Vector2 timeAreaScale { get { return m_Window.timeArea.scale; } }
public Rect timeAreaRect { get { var sequenceContentRect = m_Window.sequenceContentRect; return new Rect( sequenceContentRect.x, WindowConstants.timeAreaYPosition, Mathf.Max(sequenceContentRect.width, WindowConstants.timeAreaMinWidth), WindowConstants.timeAreaHeight ); } }
public float windowHeight { get { return m_Window.position.height; } }
public bool playRangeEnabled { get { return !EditorApplication.isPlaying && masterSequence.viewModel.playRangeEnabled && !IsEditingASubTimeline(); } set { if (EditorApplication.isPlaying) return;
masterSequence.viewModel.playRangeEnabled = value; } }
public TimelineWindow GetWindow() { return m_Window; }
public void Play() { if (masterSequence.director == null) return;
if (!previewMode) previewMode = true;
if (previewMode) { if (masterSequence.time > masterSequence.duration) masterSequence.time = 0;
masterSequence.director.Play(); masterSequence.director.ProcessPendingGraphChanges(); PlayableDirector.ResetFrameTiming(); InvokePlayStateChangeCallback(true); } }
public void Pause() { if (masterSequence.director != null) { masterSequence.director.Pause(); masterSequence.director.ProcessPendingGraphChanges(); SynchronizeSequencesAfterPlayback(); InvokePlayStateChangeCallback(false); } }
public void SetPlaying(bool start) { if (start && !playing) { Play(); }
if (!start && playing) { Pause(); } }
public void Stop() { if (masterSequence.director != null) { masterSequence.director.Stop(); masterSequence.director.ProcessPendingGraphChanges(); InvokePlayStateChangeCallback(false); } }
void InvokePlayStateChangeCallback(bool isPlaying) { if (OnPlayStateChange != null) OnPlayStateChange.Invoke(isPlaying); }
public void RebuildPlayableGraph() { if (masterSequence.director != null) { masterSequence.director.RebuildGraph(); // rebuild both the parent and the edit sequences. control tracks don't necessary
// rebuild the subdirector on recreation
if (editSequence.director != null && editSequence.director != masterSequence.director) { editSequence.director.RebuildGraph(); } } }
public void Evaluate() { if (masterSequence.director != null) { if (!EditorApplication.isPlaying && !previewMode) GatherProperties(masterSequence.director);
ForceTimeOnDirector(masterSequence.director); masterSequence.director.DeferredEvaluate();
if (EditorApplication.isPlaying == false) { PreviewEditorWindow.RepaintAll(); SceneView.RepaintAll(); AudioMixerWindow.RepaintAudioMixerWindow(); } } }
public void EvaluateImmediate() { if (masterSequence.director != null) { if (!EditorApplication.isPlaying && !previewMode) GatherProperties(masterSequence.director);
if (previewMode) { ForceTimeOnDirector(masterSequence.director); masterSequence.director.ProcessPendingGraphChanges(); masterSequence.director.Evaluate(); } } }
public void Refresh() { CheckRecordingState(); dirtyStamp = dirtyStamp + 1;
rebuildGraph = true; }
public void UpdateViewStateHash() { viewStateHash = timeAreaTranslation.GetHashCode() .CombineHash(timeAreaScale.GetHashCode()) .CombineHash(trackScale.GetHashCode()); }
public bool IsEditingASubItem() { return IsCurrentEditingASequencerTextField() || !SelectionManager.IsCurveEditorFocused(null); }
public bool IsEditingASubTimeline() { return editSequence != masterSequence; }
public bool IsEditingAnEmptyTimeline() { return editSequence.asset == null; }
public bool IsEditingAPrefabAsset() { var stage = PrefabStageUtility.GetCurrentPrefabStage(); return stage != null && editSequence.director != null && stage.IsPartOfPrefabContents(editSequence.director.gameObject); }
public bool IsCurrentEditingASequencerTextField() { if (editSequence.asset == null) return false;
if (k_TimeCodeTextFieldId == GUIUtility.keyboardControl) return true;
return editSequence.asset.flattenedTracks.Count(t => t.GetInstanceID() == GUIUtility.keyboardControl) != 0; }
public float TimeToTimeAreaPixel(double t) // TimeToTimeAreaPixel
{ float pixelX = (float)t; pixelX *= timeAreaScale.x; pixelX += timeAreaTranslation.x + sequencerHeaderWidth; return pixelX; }
public float TimeToScreenSpacePixel(double time) { float pixelX = (float)time; pixelX *= timeAreaScale.x; pixelX += timeAreaTranslation.x; return pixelX; }
public float TimeToPixel(double time) { return m_Window.timeArea.TimeToPixel((float)time, timeAreaRect); }
public float PixelToTime(float pixel) { return m_Window.timeArea.PixelToTime(pixel, timeAreaRect); }
public float PixelDeltaToDeltaTime(float p) { return PixelToTime(p) - PixelToTime(0); }
public float TimeAreaPixelToTime(float pixel) { return PixelToTime(pixel); }
public float ScreenSpacePixelToTimeAreaTime(float p) { // transform into track space by offsetting the pixel by the screen-space offset of the time area
p -= timeAreaRect.x; return TrackSpacePixelToTimeAreaTime(p); }
public float TrackSpacePixelToTimeAreaTime(float p) { p -= timeAreaTranslation.x;
if (timeAreaScale.x > 0.0f) return p / timeAreaScale.x;
return p; }
public void OffsetTimeArea(int pixels) { Vector3 tx = timeAreaTranslation; tx.x += pixels; SetTimeAreaTransform(tx, timeAreaScale); }
public GameObject GetSceneReference(TrackAsset asset) { if (editSequence.director == null) return null; // no player bound
return TimelineUtility.GetSceneGameObject(editSequence.director, asset); }
public void CalculateRowRects() { // arming a track might add inline curve tracks, recalc track heights
if (m_Window != null && m_Window.treeView != null) m_Window.treeView.CalculateRowRects(); }
// Only one track within a 'track' hierarchy can be armed
public void ArmForRecord(TrackAsset track) { m_ArmedTracks[TimelineUtility.GetSceneReferenceTrack(track)] = track; if (track != null && !recording) recording = true; if (!recording) return;
track.OnRecordingArmed(editSequence.director); CalculateRowRects(); }
public void UnarmForRecord(TrackAsset track) { m_ArmedTracks.Remove(TimelineUtility.GetSceneReferenceTrack(track)); if (m_ArmedTracks.Count == 0) recording = false; track.OnRecordingUnarmed(editSequence.director); }
public void UpdateRecordingState() { if (recording) { foreach (var track in m_ArmedTracks.Values) { if (track != null) track.OnRecordingTimeChanged(editSequence.director); } } }
public bool IsTrackRecordable(TrackAsset track) { // A track with animated parameters can always be recorded to
return IsArmedForRecord(track) || track.HasAnyAnimatableParameters(); }
public bool IsArmedForRecord(TrackAsset track) { return track == GetArmedTrack(track); }
public TrackAsset GetArmedTrack(TrackAsset track) { TrackAsset outTrack; m_ArmedTracks.TryGetValue(TimelineUtility.GetSceneReferenceTrack(track), out outTrack); return outTrack; }
void CheckRecordingState() { // checks for deleted tracks, and makes sure the recording state matches
if (m_ArmedTracks.Any(t => t.Value == null)) { m_ArmedTracks = m_ArmedTracks.Where(t => t.Value != null).ToDictionary(t => t.Key, t => t.Value); if (m_ArmedTracks.Count == 0) recording = false; } }
void OnCurrentDirectorWillChange() { SynchronizeViewModelTime(editSequence);
if (!Application.isPlaying) Stop();
rebuildGraph = true; // needed for asset previews
}
public void GatherProperties(PlayableDirector director) { if (director == null || Application.isPlaying) return;
var asset = director.playableAsset as TimelineAsset;
if (!previewMode) { AnimationMode.StartAnimationMode(previewDriver);
OnStartPreview(director);
AnimationPropertyContextualMenu.Instance.SetResponder(new TimelineRecordingContextualResponder(this)); if (!previewMode) return; EnsureWindowTimeConsistency(); }
if (asset != null) { m_PropertyCollector.Reset(); m_PropertyCollector.PushActiveGameObject(null); // avoid overflow on unbound tracks
asset.GatherProperties(director, m_PropertyCollector); } }
void OnStartPreview(PlayableDirector director) { previewedDirectors = TimelineUtility.GetAllDirectorsInHierarchy(director).ToList();
if (previewedDirectors == null) return;
m_PreviewedAnimators = TimelineUtility.GetBindingsFromDirectors<Animator>(previewedDirectors).ToList();
m_PreviewedComponents = new List<IAnimationWindowPreview>(); foreach (var animator in m_PreviewedAnimators) { m_PreviewedComponents.AddRange(animator.GetComponents<IAnimationWindowPreview>()); } foreach (var previewedComponent in m_PreviewedComponents) { previewedComponent.StartPreview(); } }
void OnStopPreview() { if (m_PreviewedComponents != null) { foreach (var previewComponent in m_PreviewedComponents) { if (previewComponent != null) { previewComponent.StopPreview(); } } m_PreviewedComponents = null; }
if (m_PreviewedAnimators != null) { foreach (var previewAnimator in m_PreviewedAnimators) { if (previewAnimator != null) { previewAnimator.UnbindAllHandles(); } } m_PreviewedAnimators = null; } }
internal void ProcessStartFramePendingUpdates() { if (m_OnStartFrameUpdates != null) m_OnStartFrameUpdates.RemoveAll(callback => callback.Invoke(this, Event.current)); }
internal void ProcessEndFramePendingUpdates() { if (m_OnEndFrameUpdates != null) m_OnEndFrameUpdates.RemoveAll(callback => callback.Invoke(this, Event.current)); }
public void AddStartFrameDelegate(PendingUpdateDelegate updateDelegate) { if (m_OnStartFrameUpdates == null) m_OnStartFrameUpdates = new List<PendingUpdateDelegate>(); if (m_OnStartFrameUpdates.Contains(updateDelegate)) return; m_OnStartFrameUpdates.Add(updateDelegate); }
public void AddEndFrameDelegate(PendingUpdateDelegate updateDelegate) { if (m_OnEndFrameUpdates == null) m_OnEndFrameUpdates = new List<PendingUpdateDelegate>(); if (m_OnEndFrameUpdates.Contains(updateDelegate)) return; m_OnEndFrameUpdates.Add(updateDelegate); }
internal void InvokeWindowOnGuiStarted(Event evt) { if (windowOnGuiStarted != null) windowOnGuiStarted.Invoke(this, evt); }
internal void InvokeWindowOnGuiFinished(Event evt) { if (windowOnGuiFinished != null) windowOnGuiFinished.Invoke(this, evt); }
public void UpdateRootPlayableDuration(double duration) { if (editSequence.director != null) { if (editSequence.director.playableGraph.IsValid()) { if (editSequence.director.playableGraph.GetRootPlayableCount() > 0) { var rootPlayable = editSequence.director.playableGraph.GetRootPlayable(0); if (rootPlayable.IsValid()) rootPlayable.SetDuration(duration); } } } }
public void InvokeTimeChangeCallback() { if (OnTimeChange != null) OnTimeChange.Invoke(); }
Vector2 ValidatePlayRange(Vector2 range) { if (range == TimelineAssetViewModel.NoPlayRangeSet) return range;
float minimumPlayRangeTime = 0.01f / Mathf.Max(1.0f, referenceSequence.frameRate);
// Validate min
if (range.y - range.x < minimumPlayRangeTime) range.x = range.y - minimumPlayRangeTime;
if (range.x < 0.0f) range.x = 0.0f;
// Validate max
if (range.y > editSequence.duration) range.y = (float)editSequence.duration;
if (range.y - range.x < minimumPlayRangeTime) range.y = Mathf.Min(range.x + minimumPlayRangeTime, (float)editSequence.duration);
return range; }
void EnsureWindowTimeConsistency() { if (Application.isPlaying || masterSequence.director == null || masterSequence.viewModel == null) return;
masterSequence.time = masterSequence.viewModel.windowTime; }
void SynchronizeSequencesAfterPlayback() { // Synchronizing editSequence will synchronize all view models up to the master
SynchronizeViewModelTime(editSequence); }
static void SynchronizeViewModelTime(ISequenceState state) { if (state.director == null || state.viewModel == null) return;
var t = state.time; state.time = t; }
// because we may be evaluating outside the duration of the root playable
// we explicitly set the time - this causes the graph to not 'advance' the time
// because advancing it can force it to change due to wrapping to the duration
// This can happen if the graph is force evaluated outside it's duration
// case 910114, 936844 and 943377
static void ForceTimeOnDirector(PlayableDirector director) { var directorTime = director.time; director.time = directorTime; } }}
|