public override void PrepareFrame(Playable playable, FrameData info) { mPlaying = info.evaluationType == FrameData.EvaluationType.Playback; #if UNITY_EDITOR && UNITY_2019_2_OR_NEWER if (Application.isPlaying || !TargetPositionCache.UseCache) { TargetPositionCache.CacheMode = TargetPositionCache.Mode.Disabled; } else { if (m_ScrubbingCacheHelper == null) { m_ScrubbingCacheHelper = new ScrubbingCacheHelper(); m_ScrubbingCacheHelper.Init(playable); } m_ScrubbingCacheHelper.ScrubToHere( (float)playable.GetGraph().GetRootPlayable(0).GetTime(), mPlaying ? TargetPositionCache.Mode.Record : TargetPositionCache.Mode.Playback, mBrain); } #else TargetPositionCache.CacheMode = TargetPositionCache.Mode.Disabled; #endif }
public override void ProcessFrame(Playable playable, FrameData info, object playerData) { base.ProcessFrame(playable, info, playerData); // Get the object that this track controls m_BrainOverrideStack = playerData as ICameraOverrideStack; if (m_BrainOverrideStack == 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; int clipIndexA = -1; int clipIndexB = -1; bool incomingIsA = false; // Assume that incoming clip is clip B float weightB = 1; for (int i = 0; i < playable.GetInputCount(); ++i) { float weight = playable.GetInputWeight(i); var clip = (ScriptPlayable <CinemachineShotPlayable>)playable.GetInput(i); CinemachineShotPlayable shot = clip.GetBehaviour(); if (shot != null && shot.IsValid && playable.GetPlayState() == PlayState.Playing && weight > 0) { clipIndexA = clipIndexB; clipIndexB = i; weightB = weight; if (++activeInputs == 2) { // Deduce which clip is incoming (timeline doesn't know) var clipA = playable.GetInput(clipIndexA); // Incoming has later start time (therefore earlier current time) incomingIsA = clip.GetTime() >= clipA.GetTime(); // If same start time, longer clip is incoming if (clip.GetTime() == clipA.GetTime()) { incomingIsA = clip.GetDuration() < clipA.GetDuration(); } break; } } } // Special case: check for only one clip that's fading out - it must be outgoing if (activeInputs == 1 && weightB < 1 && playable.GetInput(clipIndexB).GetTime() > playable.GetInput(clipIndexB).GetDuration() / 2) { incomingIsA = true; } if (incomingIsA) { (clipIndexA, clipIndexB) = (clipIndexB, clipIndexA); weightB = 1 - weightB; } ICinemachineCamera camA = null; if (clipIndexA >= 0) { CinemachineShotPlayable shot = ((ScriptPlayable <CinemachineShotPlayable>)playable.GetInput(clipIndexA)).GetBehaviour(); camA = shot.VirtualCamera; } ICinemachineCamera camB = null; if (clipIndexB >= 0) { CinemachineShotPlayable shot = ((ScriptPlayable <CinemachineShotPlayable>)playable.GetInput(clipIndexB)).GetBehaviour(); camB = shot.VirtualCamera; } // Override the Cinemachine brain with our results m_BrainOverrideId = m_BrainOverrideStack.SetCameraOverride( m_BrainOverrideId, camA, camB, weightB, GetDeltaTime(info.deltaTime)); #if UNITY_EDITOR && UNITY_2019_2_OR_NEWER if (m_ScrubbingCacheHelper != null && TargetPositionCache.CacheMode != TargetPositionCache.Mode.Disabled) { bool isNewB = (m_ScrubbingCacheHelper.ActivePlayableA != clipIndexB && m_ScrubbingCacheHelper.ActivePlayableB != clipIndexB); m_ScrubbingCacheHelper.ActivePlayableA = clipIndexA; m_ScrubbingCacheHelper.ActivePlayableB = clipIndexB; if (clipIndexA >= 0) { m_ScrubbingCacheHelper.ScrubToHere( (float)GetMasterPlayableDirector().time, clipIndexA, false, (float)playable.GetInput(clipIndexA).GetTime(), m_BrainOverrideStack.DefaultWorldUp); } if (clipIndexB >= 0) { m_ScrubbingCacheHelper.ScrubToHere( (float)GetMasterPlayableDirector().time, clipIndexB, isNewB && weightB > 0.99f, (float)playable.GetInput(clipIndexB).GetTime(), m_BrainOverrideStack.DefaultWorldUp); } } #endif }