protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks) { if (tracks.Any(track => TimelineUtility.IsParentMuted(track))) { return(MenuActionDisplayState.Disabled); } return(MenuActionDisplayState.Visible); }
public GameObject GetSceneReference(TrackAsset asset) { if (editSequence.director == null) { return(null); // no player bound } return(TimelineUtility.GetSceneGameObject(editSequence.director, asset)); }
private static bool IsValidClip(TimelineClip clip, PlayableDirector director) { return(clip != null && clip.parentTrack != null && (clip.asset as AnimationPlayableAsset) != null && clip.parentTrack.clips.Any(x => x.start > clip.start) && TimelineUtility.GetSceneGameObject(director, clip.parentTrack) != null); }
bool IsLocked() { if (!TimelineUtility.IsCurrentSequenceValid() || IsCurrentSequenceReadOnly()) { return(true); } return(targets.OfType <EditorClip>().Any(t => t.clip.GetParentTrack() != null && t.clip.GetParentTrack().lockedInHierarchy)); }
public void FromSequencePath(SequencePath path, bool forceRebuild) { if (!NeedsUpdate(path, forceRebuild)) { return; } Clear_Internal(); var rootObject = EditorUtility.InstanceIDToObject(path.selectionRoot); if (rootObject == null) { UpdateSerializedPath(); return; } var candidateAsset = rootObject as TimelineAsset; if (candidateAsset != null) { Add_Internal(candidateAsset, null, null); UpdateSerializedPath(); return; } var candidateGameObject = rootObject as GameObject; if (candidateGameObject == null) { UpdateSerializedPath(); return; } var director = TimelineUtility.GetDirectorComponentForGameObject(candidateGameObject); var asset = TimelineUtility.GetTimelineAssetForDirectorComponent(director); Add_Internal(asset, director, null); if (!path.subElements.Any()) { UpdateSerializedPath(); return; } List <SequenceBuildingBlock> buildingBlocks; if (ValidateSubElements(path.subElements, director, out buildingBlocks)) { foreach (var buildingBlock in buildingBlocks) { Add_Internal(buildingBlock.asset, buildingBlock.director, buildingBlock.hostClip); } } UpdateSerializedPath(); }
private static void SetTrackBinding(ITimelineState state, TrackAsset track, GameObject gameObjectToBind) { if (state != null) { state.previewMode = false; TimelineUtility.SetSceneGameObject(state.currentDirector, track, gameObjectToBind); state.rebuildGraph = true; } }
protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks) { if (tracks.Any(track => TimelineUtility.IsParentMuted(track) || track is GroupTrack || !track.subTracksObjects.Any())) { return(MenuActionDisplayState.Hidden); } return(MenuActionDisplayState.Visible); }
public override ActionValidity Validate(IEnumerable <TrackAsset> tracks) { UpdateMenuName(tracks); if (tracks.Any(track => TimelineUtility.IsParentMuted(track) || track is GroupTrack || !track.subTracksObjects.Any())) { return(ActionValidity.NotApplicable); } return(ActionValidity.Valid); }
protected bool IsTrackLocked() { if (!TimelineUtility.IsCurrentSequenceValid() || IsCurrentSequenceReadOnly()) { return(true); } return(targets.Any(track => ((TrackAsset)track).lockedInHierarchy)); }
public void UnarmForRecord(TrackAsset track) { m_ArmedTracks.Remove(TimelineUtility.GetSceneReferenceTrack(track)); if (m_ArmedTracks.Count == 0) { recording = false; } track.OnRecordingUnarmed(editSequence.director); }
protected override MenuActionDisplayState GetDisplayState(WindowState state, TrackAsset[] tracks) { bool hasUnlockableTracks = tracks.Any(x => TimelineUtility.IsLockedFromGroup(x)); if (hasUnlockableTracks) { return(MenuActionDisplayState.Disabled); } return(MenuActionDisplayState.Visible); }
void DrawNoSequenceGUI(WindowState windowState) { bool showCreateButton = false; var currentlySelectedGo = UnityEditor.Selection.activeObject != null ? UnityEditor.Selection.activeObject as GameObject : null; var textContent = DirectorStyles.noTimelineAssetSelected; var existingDirector = currentlySelectedGo != null?currentlySelectedGo.GetComponent <PlayableDirector>() : null; var existingAsset = existingDirector != null ? existingDirector.playableAsset : null; if (currentlySelectedGo != null && !TimelineUtility.IsPrefabOrAsset(currentlySelectedGo) && existingAsset == null) { showCreateButton = true; textContent = new GUIContent(String.Format(DirectorStyles.createTimelineOnSelection.text, currentlySelectedGo.name, "a Director component and a Timeline asset")); } GUILayout.FlexibleSpace(); GUILayout.BeginVertical(); GUILayout.FlexibleSpace(); GUILayout.Label(textContent); if (showCreateButton) { GUILayout.BeginHorizontal(); var textSize = GUI.skin.label.CalcSize(textContent); GUILayout.Space((textSize.x / 2.0f) - (WindowConstants.createButtonWidth / 2.0f)); if (GUILayout.Button("Create", GUILayout.Width(WindowConstants.createButtonWidth))) { var message = DirectorStyles.createNewTimelineText.text + " '" + currentlySelectedGo.name + "'"; string newSequencePath = EditorUtility.SaveFilePanelInProject(DirectorStyles.createNewTimelineText.text, currentlySelectedGo.name + "Timeline", "playable", message, ProjectWindowUtil.GetActiveFolderPath()); if (!string.IsNullOrEmpty(newSequencePath)) { var newAsset = TimelineUtility.CreateAndSaveTimelineAsset(newSequencePath); Undo.IncrementCurrentGroup(); if (existingDirector == null) { existingDirector = Undo.AddComponent <PlayableDirector>(currentlySelectedGo); } existingDirector.playableAsset = newAsset; SetCurrentTimeline(existingDirector); windowState.previewMode = false; } // If we reach this point, the state of the pannel has changed; skip the rest of this GUI phase // Fixes: case 955831 - [OSX] NullReferenceException when creating a timeline on a selected object GUIUtility.ExitGUI(); } GUILayout.EndHorizontal(); } GUILayout.FlexibleSpace(); GUILayout.EndVertical(); GUILayout.FlexibleSpace(); }
public static void SetLockState(TrackAsset[] tracks, bool shouldLock, WindowState state = null) { if (tracks.Length == 0) { return; } foreach (var track in tracks) { if (TimelineUtility.IsLockedFromGroup(track)) { continue; } if (track as GroupTrack == null) { SetLockState(track.GetChildTracks().ToArray(), shouldLock, state); } TimelineUndo.PushUndo(track, "Lock Tracks"); track.locked = shouldLock; } if (state != null) { // find the tracks we've locked. unselect anything locked and remove recording. foreach (var track in tracks) { if (TimelineUtility.IsLockedFromGroup(track) || !track.locked) { continue; } var flattenedChildTracks = track.GetFlattenedChildTracks(); foreach (var i in track.clips) { SelectionManager.Remove(i); } state.UnarmForRecord(track); foreach (var child in flattenedChildTracks) { SelectionManager.Remove(child); state.UnarmForRecord(child); foreach (var clip in child.GetClips()) { SelectionManager.Remove(clip); } } } // no need to rebuild, just repaint (including inspectors) InspectorWindow.RepaintAllInspectors(); state.editorWindow.Repaint(); } }
// 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.IsTrackRecordable(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.IsTrackRecordable(result)) { result = null; } return(result); }
// 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(); }
protected static void DrawTrackStateBox(Rect trackRect, TrackAsset track) { const float k_LockTextPadding = 40f; var styles = DirectorStyles.Instance; bool locked = track.locked && !track.parentLocked; bool muted = track.muted && !TimelineUtility.IsParentMuted(track); bool allSubTrackMuted = TimelineUtility.IsAllSubTrackMuted(track); GUIContent content = null; if (locked && muted) { content = Styles.s_LockedAndMuted; if (!allSubTrackMuted) { content = Styles.s_LockedAndPartiallyMuted; } } else if (locked) { content = Styles.s_Locked; } else if (muted) { content = Styles.s_Muted; if (!allSubTrackMuted) { content = Styles.s_PartiallyMuted; } } // the track could be locked, but we only show the 'locked portion' on the upper most track // that is causing the lock if (content == null) { return; } var textRect = trackRect; textRect.width = styles.fontClip.CalcSize(content).x + k_LockTextPadding; textRect.x += (trackRect.width - textRect.width) / 2f; textRect.height -= 4f; textRect.y += 2f; using (new GUIColorOverride(styles.customSkin.colorLockTextBG)) { GUI.Box(textRect, GUIContent.none, styles.displayBackground); } Timeline.Graphics.ShadowLabel(textRect, content, styles.fontClip, Color.white, Color.black); }
public override ActionValidity Validate(IEnumerable <TimelineClip> clips) { if (clips == null || clips.Count() != 1 || TimelineEditor.inspectedDirector == null) { return(ActionValidity.NotApplicable); } var clip = clips.First(); var directors = TimelineUtility.GetSubTimelines(clip, TimelineEditor.inspectedDirector); return(directors.Any(x => x != null) ? ActionValidity.Valid : ActionValidity.NotApplicable); }
public override bool Execute(WindowState state, TrackAsset[] tracks) { if (!tracks.Any() || tracks.Any(track => TimelineUtility.IsParentMuted(track))) { return(false); } var hasUnmutedTracks = tracks.Any(x => !x.muted); Mute(state, tracks, hasUnmutedTracks); return(true); }
bool IsValid(WindowState state, TimelineClip[] clips) { if (clips.Length != 1 || state == null || state.editSequence.director == null) { return(false); } var clip = clips[0]; var directors = TimelineUtility.GetSubTimelines(clip, state.editSequence.director); return(directors.Any(x => x != null)); }
public IEnumerable <SequenceContext> GetSubSequences() { var contexts = editSequence.asset?.flattenedTracks .SelectMany(x => x.clips) .Where((TimelineUtility.HasCustomEditor)) .SelectMany((clip => TimelineUtility.GetSubTimelines(clip, TimelineEditor.inspectedDirector) .Select(director => new SequenceContext(director, clip)))); return(contexts); }
static bool DoesTrackAllowsRecording(TrackAsset track) { // if the root animation track is in auto mode, recording is not allowed var animTrack = TimelineUtility.GetSceneReferenceTrack(track) as AnimationTrack; if (animTrack != null) { return(animTrack.trackOffset != TrackOffset.Auto); } return(false); }
// Given a serialized property, gathers all animatable properties static void GatherModifications(SerializedProperty property, List <PropertyModification> modifications) { // handles child properties (Vector3 is 3 recordable properties) if (property.hasChildren) { var iter = property.Copy(); var end = property.GetEndProperty(false); // recurse over all children properties while (iter.Next(true) && !SerializedProperty.EqualContents(iter, end)) { GatherModifications(iter, modifications); } } var isObject = property.propertyType == SerializedPropertyType.ObjectReference; var isFloat = property.propertyType == SerializedPropertyType.Float || property.propertyType == SerializedPropertyType.Boolean || property.propertyType == SerializedPropertyType.Integer; if (isObject || isFloat) { var serializedObject = property.serializedObject; var modification = new PropertyModification(); modification.target = serializedObject.targetObject; modification.propertyPath = property.propertyPath; if (isObject) { modification.value = string.Empty; modification.objectReference = property.objectReferenceValue; } else { modification.value = TimelineUtility.PropertyToString(property); } // Path for monobehaviour based - better to grab the component to get the curvebinding to allow validation if (serializedObject.targetObject is Component) { EditorCurveBinding temp; var go = ((Component)serializedObject.targetObject).gameObject; if (AnimationUtility.PropertyModificationToEditorCurveBinding(modification, go, out temp) != null) { modifications.Add(modification); } } else { modifications.Add(modification); } } }
public static void SetLockState(IEnumerable <TrackAsset> tracks, bool shouldLock) { if (!tracks.Any()) { return; } foreach (var track in tracks) { if (TimelineUtility.IsLockedFromGroup(track)) { continue; } if (track as GroupTrack == null) { SetLockState(track.GetChildTracks().ToArray(), shouldLock); } TimelineUndo.PushUndo(track, L10n.Tr("Lock Tracks")); track.locked = shouldLock; } // find the tracks we've locked. unselect anything locked and remove recording. foreach (var track in tracks) { if (TimelineUtility.IsLockedFromGroup(track) || !track.locked) { continue; } var flattenedChildTracks = track.GetFlattenedChildTracks(); foreach (var i in track.clips) { SelectionManager.Remove(i); } track.UnarmForRecord(); foreach (var child in flattenedChildTracks) { SelectionManager.Remove(child); child.UnarmForRecord(); foreach (var clip in child.GetClips()) { SelectionManager.Remove(clip); } } } // no need to rebuild, just repaint (including inspectors) InspectorWindow.RepaintAllInspectors(); TimelineEditor.Refresh(RefreshReason.WindowNeedsRedraw); }
internal override bool IsEnabled() { if (!TimelineUtility.IsCurrentSequenceValid() || IsCurrentSequenceReadOnly()) { return(false); } if (m_TimelineAsset != TimelineWindow.instance.state.editSequence.asset) { return(false); } return(base.IsEnabled()); }
public static void Mute(WindowState state, TrackAsset[] tracks, bool shouldMute) { if (tracks.Length == 0) { return; } foreach (var track in tracks.Where(t => !TimelineUtility.IsParentMuted(t))) { TimelineUndo.PushUndo(track, "Mute Tracks"); track.muted = shouldMute; } state.Refresh(); }
protected void DrawMuteButton(Rect rect, WindowState state) { using (new EditorGUI.DisabledScope(TimelineUtility.IsParentMuted(track))) { EditorGUI.BeginChangeCheck(); var isMuted = track.mutedInHierarchy; var tooltip = isMuted ? Styles.trackMuteBtnOnTooltip : Styles.trackMuteBtnOffTooltip; var muted = GUI.Toggle(rect, isMuted, tooltip, TimelineWindow.styles.trackMuteButton); if (EditorGUI.EndChangeCheck()) { MuteTrack.Mute(new[] { track }, muted); } } }
protected void DrawLockButton(Rect rect, WindowState state) { using (new EditorGUI.DisabledScope(TimelineUtility.IsLockedFromGroup(track))) { EditorGUI.BeginChangeCheck(); var isLocked = track.lockedInHierarchy; var tooltip = isLocked ? Styles.trackLockBtnOnTooltip : Styles.trackLockBtnOffTooltip; var locked = GUI.Toggle(rect, track.lockedInHierarchy, tooltip, TimelineWindow.styles.trackLockButton); if (EditorGUI.EndChangeCheck()) { LockTrack.SetLockState(new[] { track }, locked); } } }
float InlineCurveHeight() { if (!track.GetShowInlineCurves()) { return(0.0f); } if (!TimelineUtility.TrackHasAnimationCurves(track)) { return(0.0f); } return(TimelineWindowViewPrefs.GetInlineCurveHeight(track)); }
public static void Lock(TrackAsset[] tracks, bool shouldlock) { if (tracks.Length == 0) { return; } foreach (var track in tracks.Where(t => !TimelineUtility.IsLockedFromGroup(t))) { TimelineUndo.PushUndo(track, L10n.Tr("Lock Tracks")); track.locked = shouldlock; } TimelineEditor.Refresh(RefreshReason.WindowNeedsRedraw); }
public static void SaveSequence(TimelineAsset timeline) { string text = AssetDatabase.GetAssetPath(Selection.get_activeObject()); if (text == "") { text = "Assets"; } else if (Path.GetExtension(text) != "") { text = text.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.get_activeObject())), ""); } TimelineUtility.SaveSequence(timeline, text); }