using UnityEngine.Playables; namespace UnityEngine.Rendering.HighDefinition { /// /// Water surface behavior for timeline support. /// public class WaterSurfaceBehaviour : PlayableBehaviour { // This needs to be kept because we it to restore the simulation as active when timeline is disabled WaterSurface m_Target = null; /// /// Function called to process a frame. /// /// Playable. /// FrameData. /// Target water surface. public override void ProcessFrame(Playable playable, FrameData info, object playerData) { // Grab the target water surface (if it has been set and the simulation has been initialized) WaterSurface waterSurface = playerData as WaterSurface; if (waterSurface != null && waterSurface.simulation != null) { // Keep track of the water surface m_Target = waterSurface; // Disable the time steps (when in timeline), right now it is done in lazy fashion m_Target.simulation.DisableTimeSteps(); // Grab the total timeline time var duration = playable.GetOutput(0).GetDuration(); var currentTime = playable.GetTime(); var numberOfFullLoops = (int)(currentTime / duration); currentTime -= numberOfFullLoops * duration; // Let's go through the Playables and add the relevant ones (partially) double currentTotalTime = 0.0; int inputCount = playable.GetInputCount(); for (int i = 0; i < inputCount; i++) { // Grab the input playable (make sure he is of the right type) Playable inputPlayable = playable.GetInput(i); if (inputPlayable.GetPlayableType() != typeof(WaterSurfacePlayableBehaviour)) continue; // Let's grab the playable behavior var waterPlayable = (ScriptPlayable)inputPlayable; WaterSurfacePlayableBehaviour wsPB = waterPlayable.GetBehaviour(); // The clip is completely before the current time if (wsPB.clipEnd <= currentTime) { currentTotalTime += (wsPB.clipEnd - wsPB.clipStart); } // The clip is partially before the current time else if (wsPB.clipStart < currentTime) { currentTotalTime += (currentTime - wsPB.clipStart); } } // Set the simulation time waterSurface.simulation.deltaTime = 1.0f / 60.0f; waterSurface.simulation.simulationTime = (float)(currentTotalTime) * waterSurface.timeMultiplier; } } /// /// Function called when the playable is destroyed. /// /// Playable. public override void OnPlayableDestroy(Playable playable) { if (m_Target != null && m_Target.simulation != null) { m_Target.simulation.EnableTimeSteps(); } } } }