ScheduleRuntimeClip.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.Audio;
  4. using UnityEngine.Playables;
  5. namespace UnityEngine.Timeline
  6. {
  7. // Special runtime clip implementation that handles playables that use a scheduling system
  8. // such as Audio
  9. internal class ScheduleRuntimeClip : RuntimeClipBase
  10. {
  11. private TimelineClip m_Clip;
  12. private Playable m_Playable;
  13. private Playable m_ParentMixer;
  14. private double m_StartDelay;
  15. private double m_FinishTail;
  16. private bool m_Started = false;
  17. // represents the start point when we want to start getting updated
  18. public override double start
  19. {
  20. get { return Math.Max(0, m_Clip.start - m_StartDelay); }
  21. }
  22. public override double duration
  23. {
  24. get { return m_Clip.duration + m_FinishTail + m_Clip.start - start; }
  25. }
  26. public void SetTime(double time)
  27. {
  28. m_Playable.SetTime(time);
  29. }
  30. public TimelineClip clip { get { return m_Clip; } }
  31. public Playable mixer { get { return m_ParentMixer; } }
  32. public Playable playable { get { return m_Playable; } }
  33. public ScheduleRuntimeClip(TimelineClip clip, Playable clipPlayable,
  34. Playable parentMixer, double startDelay = 0.2, double finishTail = 0.1)
  35. {
  36. Create(clip, clipPlayable, parentMixer, startDelay, finishTail);
  37. }
  38. private void Create(TimelineClip clip, Playable clipPlayable, Playable parentMixer,
  39. double startDelay, double finishTail)
  40. {
  41. m_Clip = clip;
  42. m_Playable = clipPlayable;
  43. m_ParentMixer = parentMixer;
  44. m_StartDelay = startDelay;
  45. m_FinishTail = finishTail;
  46. clipPlayable.Pause();
  47. }
  48. public override bool enable
  49. {
  50. set
  51. {
  52. if (value && m_Playable.GetPlayState() != PlayState.Playing)
  53. {
  54. m_Playable.Play();
  55. }
  56. else if (!value && m_Playable.GetPlayState() != PlayState.Paused)
  57. {
  58. m_Playable.Pause();
  59. if (m_ParentMixer.IsValid())
  60. m_ParentMixer.SetInputWeight(m_Playable, 0.0f);
  61. }
  62. m_Started &= value;
  63. }
  64. }
  65. public override void EvaluateAt(double localTime, FrameData frameData)
  66. {
  67. if (frameData.timeHeld)
  68. {
  69. enable = false;
  70. return;
  71. }
  72. bool forceSeek = frameData.seekOccurred || frameData.timeLooped || frameData.evaluationType == FrameData.EvaluationType.Evaluate;
  73. // If we are in the tail region of the clip, then dont do anything
  74. if (localTime > start + duration - m_FinishTail)
  75. return;
  76. // this may set the weight to 1 in a delay, but it will avoid missing the start
  77. float weight = clip.EvaluateMixIn(localTime) * clip.EvaluateMixOut(localTime);
  78. if (mixer.IsValid())
  79. mixer.SetInputWeight(playable, weight);
  80. // localTime of the sequence to localtime of the clip
  81. if (!m_Started || forceSeek)
  82. {
  83. // accounts for clip in and speed
  84. double clipTime = clip.ToLocalTime(Math.Max(localTime, clip.start));
  85. // multiply by the time scale so the delay is local to the clip
  86. // Audio will rescale based on it's effective time scale (which includes the parent)
  87. double startDelay = Math.Max(clip.start - localTime, 0) * clip.timeScale;
  88. double durationLocal = m_Clip.duration * clip.timeScale;
  89. if (m_Playable.IsPlayableOfType<AudioClipPlayable>())
  90. ((AudioClipPlayable)m_Playable).Seek(clipTime, startDelay, durationLocal);
  91. m_Started = true;
  92. }
  93. }
  94. }
  95. }