SequenceState.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.Playables;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. class SequenceState : ISequenceState
  8. {
  9. readonly WindowState m_WindowState;
  10. readonly SequenceState m_ParentSequence;
  11. double m_Time;
  12. Range? m_CachedEvaluableRange;
  13. public TimelineAsset asset { get; }
  14. public PlayableDirector director { get; }
  15. public TimelineClip hostClip { get; }
  16. public double start { get; }
  17. public double timeScale { get; }
  18. public double duration
  19. {
  20. get
  21. {
  22. if (asset == null)
  23. return 0.0;
  24. var assetDuration = asset.durationMode == TimelineAsset.DurationMode.FixedLength ? asset.fixedDuration : asset.duration;
  25. return hostClip == null ? assetDuration : Math.Min(hostClip.duration, assetDuration);
  26. }
  27. }
  28. bool? m_IsReadOnly;
  29. public bool isReadOnly
  30. {
  31. get
  32. {
  33. if (!m_IsReadOnly.HasValue)
  34. m_IsReadOnly = FileUtil.IsReadOnly(asset);
  35. return m_IsReadOnly.Value;
  36. }
  37. }
  38. public void ResetIsReadOnly()
  39. {
  40. m_IsReadOnly = null;
  41. }
  42. public TimelineAssetViewModel viewModel
  43. {
  44. get
  45. {
  46. return TimelineWindowViewPrefs.GetOrCreateViewModel(asset);
  47. }
  48. }
  49. public double time
  50. {
  51. get
  52. {
  53. if (m_ParentSequence != null)
  54. return hostClip.ToLocalTimeUnbound(m_ParentSequence.time);
  55. return GetLocalTime();
  56. }
  57. set
  58. {
  59. var correctedValue = Math.Min(value, TimeUtility.k_MaxTimelineDurationInSeconds);
  60. viewModel.windowTime = correctedValue;
  61. if (m_ParentSequence != null)
  62. m_ParentSequence.time = hostClip.FromLocalTimeUnbound(correctedValue);
  63. else
  64. SetLocalTime(correctedValue);
  65. }
  66. }
  67. public int frame
  68. {
  69. get { return TimeUtility.ToFrames(time, frameRate); }
  70. set { time = TimeUtility.FromFrames(Mathf.Max(0, value), frameRate); }
  71. }
  72. public float frameRate
  73. {
  74. get
  75. {
  76. if (asset != null)
  77. return asset.editorSettings.fps;
  78. return TimelineAsset.EditorSettings.kDefaultFps;
  79. }
  80. set
  81. {
  82. TimelineAsset.EditorSettings settings = asset.editorSettings;
  83. if (Math.Abs(settings.fps - value) > TimeUtility.kFrameRateEpsilon)
  84. {
  85. settings.fps = Mathf.Max(value, (float)TimeUtility.kFrameRateEpsilon);
  86. EditorUtility.SetDirty(asset);
  87. }
  88. }
  89. }
  90. public SequenceState(WindowState windowState, TimelineAsset asset, PlayableDirector director, TimelineClip hostClip, SequenceState parentSequence)
  91. {
  92. m_WindowState = windowState;
  93. m_ParentSequence = parentSequence;
  94. this.asset = asset;
  95. this.director = director;
  96. this.hostClip = hostClip;
  97. start = hostClip == null ? 0.0 : hostClip.start;
  98. timeScale = hostClip == null ? 1.0 : hostClip.timeScale * parentSequence.timeScale;
  99. }
  100. public Range GetEvaluableRange()
  101. {
  102. if (hostClip == null)
  103. return new Range
  104. {
  105. start = 0.0,
  106. end = duration
  107. };
  108. if (!m_CachedEvaluableRange.HasValue)
  109. {
  110. var globalRange = GetGlobalEvaluableRange();
  111. m_CachedEvaluableRange = new Range
  112. {
  113. start = ToLocalTime(globalRange.start),
  114. end = ToLocalTime(globalRange.end)
  115. };
  116. }
  117. return m_CachedEvaluableRange.Value;
  118. }
  119. public string TimeAsString(double timeValue, string format = "F2")
  120. {
  121. if (TimelinePreferences.instance.timeUnitInFrame)
  122. return TimeUtility.TimeAsFrames(timeValue, frameRate, format);
  123. return TimeUtility.TimeAsTimeCode(timeValue, frameRate, format);
  124. }
  125. public double ToGlobalTime(double t)
  126. {
  127. if (hostClip == null)
  128. return t;
  129. return m_ParentSequence.ToGlobalTime(hostClip.FromLocalTimeUnbound(t));
  130. }
  131. public double ToLocalTime(double t)
  132. {
  133. if (hostClip == null)
  134. return t;
  135. return hostClip.ToLocalTimeUnbound(m_ParentSequence.ToLocalTime(t));
  136. }
  137. double GetLocalTime()
  138. {
  139. if (!m_WindowState.previewMode && !Application.isPlaying)
  140. return viewModel.windowTime;
  141. // the time needs to always be synchronized with the director
  142. if (director != null)
  143. m_Time = director.time;
  144. return m_Time;
  145. }
  146. void SetLocalTime(double newTime)
  147. {
  148. // do this prior to the calback, because the callback pulls from the get
  149. if (director != null)
  150. director.time = newTime;
  151. if (Math.Abs(m_Time - newTime) > TimeUtility.kTimeEpsilon)
  152. {
  153. m_Time = newTime;
  154. m_WindowState.InvokeTimeChangeCallback();
  155. }
  156. }
  157. Range GetGlobalEvaluableRange()
  158. {
  159. if (hostClip == null)
  160. return new Range
  161. {
  162. start = 0.0,
  163. end = duration
  164. };
  165. var currentRange = new Range
  166. {
  167. start = hostClip.ToLocalTimeUnbound(ToGlobalTime(hostClip.start)),
  168. end = hostClip.ToLocalTimeUnbound(ToGlobalTime(hostClip.end))
  169. };
  170. return Range.Intersection(currentRange, m_ParentSequence.GetGlobalEvaluableRange());
  171. }
  172. public void Dispose()
  173. {
  174. TimelineWindowViewPrefs.SaveViewModel(asset);
  175. }
  176. }
  177. }