using System; using System.Collections.Generic; using UnityEngine; namespace CinemaDirector { /// /// The main organizational unit of a Cutscene, The TrackGroup contains tracks. /// [TrackGroupAttribute("Track Group", TimelineTrackGenre.GlobalTrack)] public abstract class TrackGroup : MonoBehaviour, IOptimizable { [SerializeField] private int ordinal = -1; // For ordering in UI [SerializeField] private bool canOptimize = true; // If true, this Track Group will load all tracks into cache on Optimize(). // A cache of the tracks for optimization purposes. protected TimelineTrack[] trackCache; // A list of the types that this Track Group is allowed to contain. protected List allowedTrackTypes; private bool hasBeenOptimized = false; /// /// Prepares the TrackGroup by caching all TimelineTracks. /// public virtual void Optimize() { if (canOptimize) { trackCache = GetTracks(); } foreach (TimelineTrack track in GetTracks()) { track.Optimize(); } hasBeenOptimized = true; } /// /// Initialize all Tracks before beginning a fresh playback. /// public virtual void Initialize() { foreach (TimelineTrack track in GetTracks()) { track.Initialize(); } } /// /// Update the track group to the current running time of the cutscene. /// /// The current running time /// The deltaTime since the last update call public virtual void UpdateTrackGroup(float time, float deltaTime) { foreach (TimelineTrack track in GetTracks()) { track.UpdateTrack(time, deltaTime); } } /// /// Pause all Track Items that this TrackGroup contains. /// public virtual void Pause() { foreach (TimelineTrack track in GetTracks()) { track.Pause(); } } /// /// Stop all Track Items that this TrackGroup contains. /// public virtual void Stop() { foreach (TimelineTrack track in GetTracks()) { track.Stop(); } } /// /// Resume all Track Items that this TrackGroup contains. /// public virtual void Resume() { foreach (TimelineTrack track in GetTracks()) { track.Resume(); } } /// /// Set this TrackGroup to the state of a given new running time. /// /// The new running time public virtual void SetRunningTime(float time) { foreach (TimelineTrack track in GetTracks()) { track.SetTime(time); } } /// /// Retrieve a list of important times for this track group within the given range. /// /// the starting time /// the ending time /// A list of ordered milestone times within the given range. public virtual List GetMilestones(float from, float to) { List times = new List(); foreach (TimelineTrack track in GetTracks()) { List trackTimes = track.GetMilestones(from, to); foreach(float f in trackTimes) { if(!times.Contains(f)) { times.Add(f); } } } times.Sort(); return times; } /// /// The Cutscene that this TrackGroup is associated with. Will return null if TrackGroup does not have a Cutscene as a parent. /// public Cutscene Cutscene { get { Cutscene cutscene = null; if (transform.parent != null) { cutscene = transform.parent.GetComponentInParent(); if (cutscene == null) { Debug.LogError("No Cutscene found on parent!", this); } } else { Debug.LogError("TrackGroup has no parent!", this); } return cutscene; } } /// /// The TimelineTracks that this TrackGroup contains. /// public virtual TimelineTrack[] GetTracks() { // Return the cache if possible if (hasBeenOptimized) { return trackCache; } List tracks = new List(); foreach (Type t in GetAllowedTrackTypes()) { var components = GetComponentsInChildren(t); foreach(var component in components) { tracks.Add((TimelineTrack)component); } } return tracks.ToArray(); } /// /// Provides a list of Types this Track Group is allowed to contain. Loaded by looking at Attributes. /// /// The list of track types. public List GetAllowedTrackTypes() { if (allowedTrackTypes == null) { allowedTrackTypes = DirectorRuntimeHelper.GetAllowedTrackTypes(this); } return allowedTrackTypes; } /// /// Ordinal for UI ranking. /// public int Ordinal { get { return ordinal; } set { ordinal = value; } } /// /// Enable this if the TrackGroup does not have Tracks added/removed during running. /// public bool CanOptimize { get { return canOptimize; } set { canOptimize = value; } } } }