// Cinema Suite using CinemaDirector.Helpers; using UnityEngine; namespace CinemaDirector { /// /// The character track group is a type of actor group, specialized for humanoid characters. /// [TrackGroupAttribute("Character Track Group", TimelineTrackGenre.CharacterTrack)] public class CharacterTrackGroup : ActorTrackGroup, IRevertable, IBakeable { // Options for reverting in editor. [SerializeField] private RevertMode editorRevertMode = RevertMode.Revert; // Options for reverting during runtime. [SerializeField] private RevertMode runtimeRevertMode = RevertMode.Revert; // Has a bake been called on this track group? private bool hasBeenBaked = false; /// /// Bake the Mecanim preview data. /// public void Bake() { if (Actor == null || Application.isPlaying) return; Animator animator = Actor.GetComponent(); if (animator == null) { return; } float frameRate = 30; int frameCount = (int)((Cutscene.Duration * frameRate) + 2); animator.StopPlayback(); animator.recorderStartTime = 0; animator.StartRecording(frameCount); for (int i = 0; i < frameCount; i++) { base.UpdateTrackGroup(i * (1.0f / frameRate), (1.0f / frameRate)); animator.Update(1.0f / frameRate); } animator.recorderStopTime = frameCount * (1.0f / frameRate); animator.StopRecording(); animator.StartPlayback(); hasBeenBaked = true; } /// /// Cache the Actor Transform. /// /// The revert info for the Actor's transform. public RevertInfo[] CacheState() { RevertInfo[] reverts = new RevertInfo[3]; if (Actor == null) return new RevertInfo[0]; reverts[0] = new RevertInfo(this, Actor.transform, "localPosition", Actor.transform.localPosition); reverts[1] = new RevertInfo(this, Actor.transform, "localRotation", Actor.transform.localRotation); reverts[2] = new RevertInfo(this, Actor.transform, "localScale", Actor.transform.localScale); return reverts; } /// /// Initialize the Track Group as normal and initialize the Animator if in Editor Mode. /// public override void Initialize() { base.Initialize(); if (!Application.isPlaying) { if (Actor == null) return; Animator animator = Actor.GetComponent(); if (animator == null) { return; } animator.StartPlayback(); } } /// /// Update the Track Group over time. If in editor mode, play the baked animator data. /// /// The new running time. /// the deltaTime since last update. public override void UpdateTrackGroup(float time, float deltaTime) { if (Application.isPlaying) { base.UpdateTrackGroup(time, deltaTime); } else { foreach (TimelineTrack track in GetTracks()) { if (!(track is MecanimTrack)) { track.UpdateTrack(time, deltaTime); } } if (Actor == null) return; Animator animator = Actor.GetComponent(); if (animator == null) { return; } animator.playbackTime = time; animator.Update(0); } } /// /// Stop this track group and stop playback on animator. /// public override void Stop() { base.Stop(); if (!Application.isPlaying) { if (hasBeenBaked) { Animator animator = Actor.GetComponent(); if (animator == null) { return; } if (animator.recorderStopTime > 0) { animator.StartPlayback(); animator.playbackTime = 0; animator.Update(0); animator.StopPlayback(); animator.Rebind(); } } } } /// /// Option for choosing when this Event will Revert to initial state in Editor. /// public RevertMode EditorRevertMode { get { return editorRevertMode; } set { editorRevertMode = value; } } /// /// Option for choosing when this Event will Revert to initial state in Runtime. /// public RevertMode RuntimeRevertMode { get { return runtimeRevertMode; } set { runtimeRevertMode = value; } } } }