using System; using System.Collections.Generic; using System.Linq; using UnityEngine; #if UNITY_2021_2_OR_NEWER using UnityEditor.SceneManagement; #else using UnityEditor.Experimental.SceneManagement; #endif using UnityEngine.Playables; using UnityEngine.Timeline; namespace UnityEditor.Timeline { partial class TimelineWindow { List m_BreadCrumbLabels = new List(100); static TitleMode GetTitleMode(ISequenceState sequence) { var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); // Top level if (sequence.hostClip == null) { if (sequence.director != null && prefabStage != null && prefabStage.IsPartOfPrefabContents(sequence.director.gameObject)) return TitleMode.Prefab; if (sequence.director != null && PrefabUtility.IsPartOfPrefabAsset(sequence.director)) return TitleMode.PrefabOutOfContext; if (sequence.director != null && !sequence.director.isActiveAndEnabled) return TitleMode.DisabledComponent; if (sequence.director != null) return TitleMode.GameObject; if (sequence.asset != null) return TitleMode.Asset; } // Subtimelines only get an error icon else if (sequence.director != null && !sequence.director.isActiveAndEnabled && !PrefabUtility.IsPartOfPrefabAsset(sequence.director)) return TitleMode.DisabledComponent; return TitleMode.None; } void DrawBreadcrumbs() { if (state == null) return; var count = 0; foreach (var sequence in state.GetAllSequences()) { var title = new BreadCrumbTitle { name = DisplayNameHelper.GetDisplayName(sequence), mode = GetTitleMode(sequence) }; if (count >= m_BreadCrumbLabels.Count) m_BreadCrumbLabels.Add(title); else m_BreadCrumbLabels[count] = title; count++; } if (m_BreadCrumbLabels.Count > count) m_BreadCrumbLabels.RemoveRange(count, m_BreadCrumbLabels.Count - count); using (new EditorGUI.DisabledScope(currentMode.headerState.breadCrumb == TimelineModeGUIState.Disabled)) { var width = position.width - WindowConstants.playControlsWidth - WindowConstants.cogButtonWidth; BreadcrumbDrawer.Draw(width, m_BreadCrumbLabels, NavigateToBreadcrumbIndex); } } void NavigateToBreadcrumbIndex(int index) { state.PopSequencesUntilCount(index + 1); } void DrawSequenceSelector() { using (new EditorGUI.DisabledScope(currentMode.headerState.sequenceSelector == TimelineModeGUIState.Disabled)) { if (EditorGUILayout.DropdownButton(DirectorStyles.timelineSelectorArrow, FocusType.Passive, DirectorStyles.Instance.sequenceSwitcher, GUILayout.Width(WindowConstants.selectorWidth))) ShowSequenceSelector(); } } void ShowSequenceSelector() { var allDirectors = TimelineUtility.GetDirectorsInSceneUsingAsset(null); var formatter = new SequenceMenuNameFormater(); var namesAndDirectors = new List>(); foreach (var d in allDirectors) { if (d.playableAsset is TimelineAsset) { var text = formatter.Format(DisplayNameHelper.GetDisplayName(d)); namesAndDirectors.Add(new ValueTuple(text, d)); } } var sequenceMenu = new GenericMenu(); foreach (var(timelineName, playableDirector) in namesAndDirectors.OrderBy(i => i.Item1)) { var isCurrent = state.masterSequence.director == playableDirector; sequenceMenu.AddItem(new GUIContent(timelineName), isCurrent, OnSequenceSelected, playableDirector); } if (allDirectors.Length == 0) sequenceMenu.AddDisabledItem(DirectorStyles.noTimelinesInScene); sequenceMenu.DropDown(EditorGUILayout.s_LastRect); } void OnSequenceSelected(object arg) { var directorToBindTo = (PlayableDirector)arg; if (directorToBindTo) { // don't just select the object, it may already be selected. SetCurrentTimeline(directorToBindTo); } } } }