TimelineWindow_Breadcrumbs.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. #if UNITY_2021_2_OR_NEWER
  6. using UnityEditor.SceneManagement;
  7. #else
  8. using UnityEditor.Experimental.SceneManagement;
  9. #endif
  10. using UnityEngine.Playables;
  11. using UnityEngine.Timeline;
  12. namespace UnityEditor.Timeline
  13. {
  14. partial class TimelineWindow
  15. {
  16. List<BreadCrumbTitle> m_BreadCrumbLabels = new List<BreadCrumbTitle>(100);
  17. static TitleMode GetTitleMode(ISequenceState sequence)
  18. {
  19. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
  20. // Top level
  21. if (sequence.hostClip == null)
  22. {
  23. if (sequence.director != null && prefabStage != null && prefabStage.IsPartOfPrefabContents(sequence.director.gameObject))
  24. return TitleMode.Prefab;
  25. if (sequence.director != null && PrefabUtility.IsPartOfPrefabAsset(sequence.director))
  26. return TitleMode.PrefabOutOfContext;
  27. if (sequence.director != null && !sequence.director.isActiveAndEnabled)
  28. return TitleMode.DisabledComponent;
  29. if (sequence.director != null)
  30. return TitleMode.GameObject;
  31. if (sequence.asset != null)
  32. return TitleMode.Asset;
  33. }
  34. // Subtimelines only get an error icon
  35. else if (sequence.director != null && !sequence.director.isActiveAndEnabled && !PrefabUtility.IsPartOfPrefabAsset(sequence.director))
  36. return TitleMode.DisabledComponent;
  37. return TitleMode.None;
  38. }
  39. void DrawBreadcrumbs()
  40. {
  41. if (state == null)
  42. return;
  43. var count = 0;
  44. foreach (var sequence in state.GetAllSequences())
  45. {
  46. var title = new BreadCrumbTitle
  47. {
  48. name = DisplayNameHelper.GetDisplayName(sequence),
  49. mode = GetTitleMode(sequence)
  50. };
  51. if (count >= m_BreadCrumbLabels.Count)
  52. m_BreadCrumbLabels.Add(title);
  53. else
  54. m_BreadCrumbLabels[count] = title;
  55. count++;
  56. }
  57. if (m_BreadCrumbLabels.Count > count)
  58. m_BreadCrumbLabels.RemoveRange(count, m_BreadCrumbLabels.Count - count);
  59. using (new EditorGUI.DisabledScope(currentMode.headerState.breadCrumb == TimelineModeGUIState.Disabled))
  60. {
  61. var width = position.width - WindowConstants.playControlsWidth - WindowConstants.cogButtonWidth;
  62. BreadcrumbDrawer.Draw(width, m_BreadCrumbLabels, NavigateToBreadcrumbIndex);
  63. }
  64. }
  65. void NavigateToBreadcrumbIndex(int index)
  66. {
  67. state.PopSequencesUntilCount(index + 1);
  68. }
  69. void DrawSequenceSelector()
  70. {
  71. using (new EditorGUI.DisabledScope(currentMode.headerState.sequenceSelector == TimelineModeGUIState.Disabled))
  72. {
  73. if (EditorGUILayout.DropdownButton(DirectorStyles.timelineSelectorArrow, FocusType.Passive, DirectorStyles.Instance.sequenceSwitcher, GUILayout.Width(WindowConstants.selectorWidth)))
  74. ShowSequenceSelector();
  75. }
  76. }
  77. void ShowSequenceSelector()
  78. {
  79. var allDirectors = TimelineUtility.GetDirectorsInSceneUsingAsset(null);
  80. var formatter = new SequenceMenuNameFormater();
  81. var namesAndDirectors = new List<ValueTuple<string, PlayableDirector>>();
  82. foreach (var d in allDirectors)
  83. {
  84. if (d.playableAsset is TimelineAsset)
  85. {
  86. var text = formatter.Format(DisplayNameHelper.GetDisplayName(d));
  87. namesAndDirectors.Add(new ValueTuple<string, PlayableDirector>(text, d));
  88. }
  89. }
  90. var sequenceMenu = new GenericMenu();
  91. foreach (var(timelineName, playableDirector) in namesAndDirectors.OrderBy(i => i.Item1))
  92. {
  93. var isCurrent = state.masterSequence.director == playableDirector;
  94. sequenceMenu.AddItem(new GUIContent(timelineName), isCurrent, OnSequenceSelected, playableDirector);
  95. }
  96. if (allDirectors.Length == 0)
  97. sequenceMenu.AddDisabledItem(DirectorStyles.noTimelinesInScene);
  98. sequenceMenu.DropDown(EditorGUILayout.s_LastRect);
  99. }
  100. void OnSequenceSelected(object arg)
  101. {
  102. var directorToBindTo = (PlayableDirector)arg;
  103. if (directorToBindTo)
  104. {
  105. // don't just select the object, it may already be selected.
  106. SetCurrentTimeline(directorToBindTo);
  107. }
  108. }
  109. }
  110. }