using UnityEngine; using UnityEngine.Playables; namespace Cinemachine.Timeline { public sealed class CinemachineMixer : PlayableBehaviour { // The brain that this track controls private CinemachineBrain mBrain; private int mBrainOverrideId = -1; private bool mPlaying; public override void OnGraphStop(Playable playable) { if (mBrain != null) mBrain.ReleaseCameraOverride(mBrainOverrideId); // clean up mBrainOverrideId = -1; } public override void ProcessFrame(Playable playable, FrameData info, object playerData) { base.ProcessFrame(playable, info, playerData); // Get the brain that this track controls. // Older versions of timeline sent the gameObject by mistake. GameObject go = playerData as GameObject; if (go == null) mBrain = (CinemachineBrain)playerData; else mBrain = go.GetComponent(); if (mBrain == null) return; // Find which clips are active. We can process a maximum of 2. // In the case that the weights don't add up to 1, the outgoing weight // will be calculated as the inverse of the incoming weight. int activeInputs = 0; ICinemachineCamera camA = null; ICinemachineCamera camB = null; float camWeight = 1f; for (int i = 0; i < playable.GetInputCount(); ++i) { CinemachineShotPlayable shot = ((ScriptPlayable)playable.GetInput(i)).GetBehaviour(); float weight = playable.GetInputWeight(i); if (shot != null && shot.VirtualCamera != null && playable.GetPlayState() == PlayState.Playing && weight > 0.0001f) { if (activeInputs == 1) camB = camA; camWeight = weight; camA = shot.VirtualCamera; ++activeInputs; if (activeInputs == 2) break; } } float deltaTime = info.deltaTime; if (!mPlaying) { if (mBrainOverrideId < 0) mLastOverrideFrame = -1; float time = Time.realtimeSinceStartup; deltaTime = Time.unscaledDeltaTime; if (!Application.isPlaying && (mLastOverrideFrame < 0 || time - mLastOverrideFrame > Time.maximumDeltaTime)) deltaTime = -1; mLastOverrideFrame = time; } // Override the Cinemachine brain with our results mBrainOverrideId = mBrain.SetCameraOverride( mBrainOverrideId, camB, camA, camWeight, deltaTime); } float mLastOverrideFrame; public override void PrepareFrame(Playable playable, FrameData info) { mPlaying = info.evaluationType == FrameData.EvaluationType.Playback; } } }