/// <summary> /// This API is specifically for Timeline. Do not use it. /// Override the current camera and current blend. This setting will trump /// any in-game logic that sets virtual camera priorities and Enabled states. /// This is the main API for the timeline. /// </summary> /// <param name="overrideId">Id to represent a specific client. An internal /// stack is maintained, with the most recent non-empty override taking precenence. /// This id must be > 0. If you pass -1, a new id will be created, and returned. /// Use that id for subsequent calls. Don't forget to /// call ReleaseCameraOverride after all overriding is finished, to /// free the OverideStack resources.</param> /// <param name="camA"> The camera to set, corresponding to weight=0</param> /// <param name="camB"> The camera to set, corresponding to weight=1</param> /// <param name="weightB">The blend weight. 0=camA, 1=camB</param> /// <param name="deltaTime">override for deltaTime. Should be Time.FixedDelta for /// time-based calculations to be included, -1 otherwise</param> /// <returns>The oiverride ID. Don't forget to call ReleaseCameraOverride /// after all overriding is finished, to free the OverideStack resources.</returns> public int SetCameraOverride( int overrideId, ICinemachineCamera camA, ICinemachineCamera camB, float weightB, float deltaTime) { if (overrideId < 0) { overrideId = mNextFrameId++; } BrainFrame frame = mFrameStack[GetBrainFrame(overrideId)]; frame.deltaTimeOverride = deltaTime; frame.blend.CamA = camA; frame.blend.CamB = camB; frame.blend.BlendCurve = mDefaultLinearAnimationCurve; frame.blend.Duration = 1; frame.blend.TimeInBlend = weightB; // In case vcams are inactive game objects, make sure they get initialized properly var cam = camA as CinemachineVirtualCameraBase; if (cam != null) { cam.EnsureStarted(); } cam = camB as CinemachineVirtualCameraBase; if (cam != null) { cam.EnsureStarted(); } return(overrideId); }
/// <summary> /// Used internally to compute the currrent blend, taking into account /// the in-game camera and all the active overrides. Caller may optionally /// exclude n topmost overrides. /// </summary> /// <param name="outputBlend">Receives the nested blend</param> /// <param name="numTopLayersToExclude">Optionaly exclude the last number /// of overrides from the blend</param> public void ComputeCurrentBlend( ref CinemachineBlend outputBlend, int numTopLayersToExclude) { // Resolve the current working frame states in the stack int lastActive = 0; int topLayer = Mathf.Max(1, mFrameStack.Count - numTopLayersToExclude); for (int i = 0; i < topLayer; ++i) { BrainFrame frame = mFrameStack[i]; if (i == 0 || frame.Active) { frame.workingBlend.CamA = frame.blend.CamA; frame.workingBlend.CamB = frame.blend.CamB; frame.workingBlend.BlendCurve = frame.blend.BlendCurve; frame.workingBlend.Duration = frame.blend.Duration; frame.workingBlend.TimeInBlend = frame.blend.TimeInBlend; if (i > 0 && !frame.blend.IsComplete) { if (frame.workingBlend.CamA == null) { if (mFrameStack[lastActive].blend.IsComplete) { frame.workingBlend.CamA = mFrameStack[lastActive].blend.CamB; } else { frame.workingBlendSource.Blend = mFrameStack[lastActive].workingBlend; frame.workingBlend.CamA = frame.workingBlendSource; } } else if (frame.workingBlend.CamB == null) { if (mFrameStack[lastActive].blend.IsComplete) { frame.workingBlend.CamB = mFrameStack[lastActive].blend.CamB; } else { frame.workingBlendSource.Blend = mFrameStack[lastActive].workingBlend; frame.workingBlend.CamB = frame.workingBlendSource; } } } lastActive = i; } } var workingBlend = mFrameStack[lastActive].workingBlend; outputBlend.CamA = workingBlend.CamA; outputBlend.CamB = workingBlend.CamB; outputBlend.BlendCurve = workingBlend.BlendCurve; outputBlend.Duration = workingBlend.Duration; outputBlend.TimeInBlend = workingBlend.TimeInBlend; }
private void UpdateFrame0(float deltaTime) { // Update the in-game frame (frame 0) BrainFrame frame = mFrameStack[0]; // Are we transitioning cameras? var activeCamera = TopCameraFromPriorityQueue(); var outGoingCamera = frame.blend.CamB; if (activeCamera != outGoingCamera) { // Do we need to create a game-play blend? if ((UnityEngine.Object)activeCamera != null && (UnityEngine.Object)outGoingCamera != null && deltaTime >= 0) { // Create a blend (curve will be null if a cut) var blendDef = LookupBlend(outGoingCamera, activeCamera); if (blendDef.BlendCurve != null && blendDef.m_Time > 0) { if (frame.blend.IsComplete) { frame.blend.CamA = outGoingCamera; // new blend } else // chain to existing blend { frame.blend.CamA = new BlendSourceVirtualCamera( new CinemachineBlend( frame.blend.CamA, frame.blend.CamB, frame.blend.BlendCurve, frame.blend.Duration, frame.blend.TimeInBlend)); } frame.blend.BlendCurve = blendDef.BlendCurve; frame.blend.Duration = blendDef.m_Time; frame.blend.TimeInBlend = 0; } } // Set the current active camera frame.blend.CamB = activeCamera; } // Advance the current blend (if any) if (frame.blend.CamA != null) { frame.blend.TimeInBlend += (deltaTime >= 0) ? deltaTime : frame.blend.Duration; if (frame.blend.IsComplete) { // No more blend frame.blend.CamA = null; frame.blend.BlendCurve = null; frame.blend.Duration = 0; frame.blend.TimeInBlend = 0; } } }
private void UpdateCurrentLiveCameras() { // Resolve the current working frame states in the stack int lastActive = 0; for (int i = 0; i < mFrameStack.Count; ++i) { BrainFrame frame = mFrameStack[i]; if (i == 0 || frame.Active) { frame.workingBlend.CamA = frame.blend.CamA; frame.workingBlend.CamB = frame.blend.CamB; frame.workingBlend.BlendCurve = frame.blend.BlendCurve; frame.workingBlend.Duration = frame.blend.Duration; frame.workingBlend.TimeInBlend = frame.blend.TimeInBlend; if (i > 0 && !frame.blend.IsComplete) { if (frame.workingBlend.CamA == null) { if (mFrameStack[lastActive].blend.IsComplete) { frame.workingBlend.CamA = mFrameStack[lastActive].blend.CamB; } else { frame.workingBlendSource.Blend = mFrameStack[lastActive].workingBlend; frame.workingBlend.CamA = frame.workingBlendSource; } } else if (frame.workingBlend.CamB == null) { if (mFrameStack[lastActive].blend.IsComplete) { frame.workingBlend.CamB = mFrameStack[lastActive].blend.CamB; } else { frame.workingBlendSource.Blend = mFrameStack[lastActive].workingBlend; frame.workingBlend.CamB = frame.workingBlendSource; } } } lastActive = i; } } var workingBlend = mFrameStack[lastActive].workingBlend; mCurrentLiveCameras.CamA = workingBlend.CamA; mCurrentLiveCameras.CamB = workingBlend.CamB; mCurrentLiveCameras.BlendCurve = workingBlend.BlendCurve; mCurrentLiveCameras.Duration = workingBlend.Duration; mCurrentLiveCameras.TimeInBlend = workingBlend.TimeInBlend; }
/// <summary> /// This API is specifically for Timeline. Do not use it. /// Override the current camera and current blend. This setting will trump /// any in-game logic that sets virtual camera priorities and Enabled states. /// This is the main API for the timeline. /// </summary> /// <param name="overrideId">Id to represent a specific client. An internal /// stack is maintained, with the most recent non-empty override taking precenence. /// This id must be > 0. If you pass -1, a new id will be created, and returned. /// Use that id for subsequent calls. Don't forget to /// call ReleaseCameraOverride after all overriding is finished, to /// free the OverideStack resources.</param> /// <param name="camA"> The camera to set, corresponding to weight=0</param> /// <param name="camB"> The camera to set, corresponding to weight=1</param> /// <param name="weightB">The blend weight. 0=camA, 1=camB</param> /// <param name="deltaTime">override for deltaTime. Should be Time.FixedDelta for /// time-based calculations to be included, -1 otherwise</param> /// <returns>The oiverride ID. Don't forget to call ReleaseCameraOverride /// after all overriding is finished, to free the OverideStack resources.</returns> internal int SetCameraOverride( int overrideId, ICinemachineCamera camA, ICinemachineCamera camB, float weightB, float deltaTime) { if (overrideId < 0) { overrideId = mNextFrameId++; } BrainFrame frame = mFrameStack[GetBrainFrame(overrideId)]; frame.deltaTimeOverride = deltaTime; frame.timeOfOverride = Time.realtimeSinceStartup; frame.blend.CamA = camA; frame.blend.CamB = camB; frame.blend.BlendCurve = AnimationCurve.Linear(0, 0, 1, 1); frame.blend.Duration = 1; frame.blend.TimeInBlend = weightB; return(overrideId); }
private void UpdateFrame0(float deltaTime) { // Make sure there is a first stack frame if (mFrameStack.Count == 0) { mFrameStack.Add(new BrainFrame()); } // Update the in-game frame (frame 0) BrainFrame frame = mFrameStack[0]; // Are we transitioning cameras? var activeCamera = TopCameraFromPriorityQueue(); var outGoingCamera = frame.blend.CamB; if (activeCamera != outGoingCamera) { // Do we need to create a game-play blend? if ((UnityEngine.Object)activeCamera != null && (UnityEngine.Object)outGoingCamera != null && deltaTime >= 0) { // Create a blend (curve will be null if a cut) var blendDef = LookupBlend(outGoingCamera, activeCamera); if (blendDef.BlendCurve != null && blendDef.BlendTime > 0) { if (frame.blend.IsComplete) { frame.blend.CamA = outGoingCamera; // new blend } else { // Special case: if backing out of a blend-in-progress // with the same blend in reverse, adjust the blend time if ((frame.blend.CamA == activeCamera || (frame.blend.CamA as BlendSourceVirtualCamera)?.Blend.CamB == activeCamera) && frame.blend.CamB == outGoingCamera && frame.blend.Duration <= blendDef.BlendTime) { blendDef.m_Time = (frame.blend.TimeInBlend / frame.blend.Duration) * blendDef.BlendTime; } // Chain to existing blend frame.blend.CamA = new BlendSourceVirtualCamera( new CinemachineBlend( frame.blend.CamA, frame.blend.CamB, frame.blend.BlendCurve, frame.blend.Duration, frame.blend.TimeInBlend)); } } frame.blend.BlendCurve = blendDef.BlendCurve; frame.blend.Duration = blendDef.BlendTime; frame.blend.TimeInBlend = 0; } // Set the current active camera frame.blend.CamB = activeCamera; } // Advance the current blend (if any) if (frame.blend.CamA != null) { frame.blend.TimeInBlend += (deltaTime >= 0) ? deltaTime : frame.blend.Duration; if (frame.blend.IsComplete) { // No more blend frame.blend.CamA = null; frame.blend.BlendCurve = null; frame.blend.Duration = 0; frame.blend.TimeInBlend = 0; } } }