/// <summary> /// The main update method of the replay manager. /// Causes the replay manager to update its state based on the current <see cref="state"/>. /// </summary> /// <param name="deltaTime"></param> public void UpdateState(float deltaTime) { if (deltaTime <= 0f) { Debug.Log(Time.timeScale); throw new InvalidOperationException("Delta time value must be greater than '0'"); } switch (state) { case PlaybackState.Idle: break; case PlaybackState.Playback_Paused: break; // Do nothing case PlaybackState.Recording_Paused: break; // Do nothing case PlaybackState.Recording_Paused_Playback: case PlaybackState.Playback: { // Make sure we are not in single frame mode if (singlePlayback == false) { ReplaySnapshot frame; // Update the sequencer ReplaySequenceResult result = sequence.UpdatePlayback(out frame, playbackEndBehaviour, deltaTime); // Check if the sequence has a new frame to be displayed if (result == ReplaySequenceResult.SequenceAdvance) { // Restore the scene state scene.RestoreSnapshot(frame, Target.InitialStateBuffer); } // Check if the sequence is at the end of the recording else if (result == ReplaySequenceResult.SequenceEnd) { StopPlayback(); } // Update the playback if (result == ReplaySequenceResult.SequenceIdle || result == ReplaySequenceResult.SequenceAdvance) { // This calls 'updateReplay' on all replay obejcts in the scene ReplayBehaviour.Events.CallReplayUpdateEvents(); } } } break; case PlaybackState.Recording: { // Update the replay timer - Pass the delta time instead of using Time.deltaTime ReplayTimer.Tick(deltaTime); // Make sure enough time has passed to record a sample if (recordStepTimer.HasElapsed() == true) { // Get the scene state ReplaySnapshot currentState = scene.RecordSnapshot(Instance.recordTimer.ElapsedSeconds, Target.InitialStateBuffer); // Write it to the replay target Target.RecordSnapshot(currentState); } } break; } }
public ReplaySequenceResult UpdatePlayback(out ReplaySnapshot frame, PlaybackEndBehaviour endBehaviour, float deltaTime) { PlaybackDirection direction = ReplayTime.TimeScaleDirection; // Default to idle ReplaySequenceResult result = ReplaySequenceResult.SequenceIdle; if (last != null) { if (direction == PlaybackDirection.Forward) { // Calculatet the delta time ReplayTime.Delta = MapScale(playbackTime, last.TimeStamp, current.TimeStamp, 0, 1); } else { // Calculate the delta for reverse playback ReplayTime.Delta = -MapScale(playbackTime, current.TimeStamp, last.TimeStamp, 0, 1); } } else { if (current == null) { ReplayTime.Delta = 0; } else { ReplayTime.Delta = MapScale(playbackTime, 0, current.TimeStamp, 0, 1); } } // Clamp delta ReplayTime.Delta = Mathf.Clamp01(ReplayTime.Delta); float delta = Mathf.Abs(deltaTime * ReplayTime.TimeScale); //if (fixedTime == true) //{ // // Find the fixed time delta // delta = (Time.fixedDeltaTime * ReplayTime.TimeScale); //} //else //{ // // Find the time delta // delta = (Time.deltaTime * Mathf.Abs(ReplayTime.TimeScale)); //} // Advance our frame switch (direction) { case PlaybackDirection.Forward: { playbackTime += delta; } break; case PlaybackDirection.Backward: { playbackTime -= delta; } break; } switch (endBehaviour) { default: case PlaybackEndBehaviour.EndPlayback: { // Check for end of playback if (playbackTime >= target.Duration || playbackTime < 0) { frame = null; return(ReplaySequenceResult.SequenceEnd); } break; } case PlaybackEndBehaviour.LoopPlayback: { if (playbackTime >= target.Duration || playbackTime < 0) { playbackTime = (direction == PlaybackDirection.Forward) ? 0 : target.Duration; } break; } case PlaybackEndBehaviour.StopPlayback: { if (playbackTime >= target.Duration) { playbackTime = target.Duration; } else if (playbackTime < 0) { playbackTime = 0; } break; } } // Try to get the current frame ReplaySnapshot temp = target.RestoreSnapshot(playbackTime); // Check for valid frame if (temp != null) { // Check for sequence advancement if (current != temp) { // Snap to next frame ReplayTime.Delta = 0; // Set the result result = ReplaySequenceResult.SequenceAdvance; // Update last frame last = current; } // Update the current frame current = temp; } else { // Do nothing - We may be inbetween replay frames // Trigger sequence end //frame = null; //return ReplaySequenceResult.SequenceEnd; } // The sequencer only updated its timing values and there was no state change frame = current; return(result); }