using TriInspector; using UnityEngine; using UnityEngine.Video; namespace R0bbie.Timeline { /// /// Video StepCmd type, used to control a video /// [AddComponentMenu("Timeline/Commands/Video (Step Command)")] [RequireComponent(typeof(Step))] public class VideoCmd : StepCmd, IPausable { // Exposed variables [Title("Video Settings")] [SerializeField] protected VideoPlayer videoPlayer; [SerializeField] protected VideoClip clip; bool eventSubscribed_VideoEndReached; /// /// Initialise command (called before Activate) /// protected override void Init() { init = true; } public override void Activate(Step _parentStep) { base.Activate(_parentStep); // TODO: Consider what the command itself should control, or pass to an external controller // What about looping videos etc? Would you want the command to start a video looping and leave it looping once the command was complete? // Complete conditions - On video end, on number of loops? // Ensure video player component is active, and set clip to the one we want to play videoPlayer.gameObject.SetActive(true); videoPlayer.clip = clip; // Listen for event when video reaches end videoPlayer.loopPointReached += VideoEndReached; eventSubscribed_VideoEndReached = true; // Play video videoPlayer.Play(); } private void VideoEndReached(VideoPlayer _videoPlayer) { // Unsubscribe from event videoPlayer.loopPointReached -= VideoEndReached; eventSubscribed_VideoEndReached = false; // Ensure video stopped videoPlayer.Stop(); // Clear clip videoPlayer.clip = null; // Complete command Complete(); } protected override void Cleanup() { active = false; } public void Pause() { if (!active) return; // Pause video videoPlayer.Pause(); } public void Resume(float _elapsedTime) { if (!active) return; // If the time paused is longer than RepeatOnResumeDelay const, then we'll repeat the animation from the start if (_elapsedTime >= StepTimeline.RepeatOnResumeDelay && !dontRepeatOnPauseResume) { RepeatFromStart(); } else { // Resume video (if currently paused) if (videoPlayer.isPaused) { videoPlayer.Play(); } } } void RepeatFromStart() { // Ensure we're still subscribed to video end event if (!eventSubscribed_VideoEndReached) { videoPlayer.loopPointReached += VideoEndReached; eventSubscribed_VideoEndReached = true; } // Reset video player to start then play videoPlayer.frame = 0; videoPlayer.Play(); } } }