/// <summary> /// Update a single Cinemachine Virtual Camera if and only if it /// hasn't already been updated this frame. Always update vcams via this method. /// Calling this more than once per frame for the same camera will have no effect. /// </summary> internal bool UpdateVirtualCamera(ICinemachineCamera vcam, Vector3 worldUp, float deltaTime) { //UnityEngine.Profiling.Profiler.BeginSample("CinemachineCore.UpdateVirtualCamera"); int now = Time.frameCount; bool isSmartUpdate = CurrentUpdateFilter != UpdateFilter.Any; bool isSmartLateUpdate = CurrentUpdateFilter == UpdateFilter.Late; if (mUpdateStatus == null) { mUpdateStatus = new Dictionary <ICinemachineCamera, UpdateStatus>(); } if (vcam.VirtualCameraGameObject == null) { if (mUpdateStatus.ContainsKey(vcam)) { mUpdateStatus.Remove(vcam); } //UnityEngine.Profiling.Profiler.EndSample(); return(false); // camera was deleted } UpdateStatus status; if (!mUpdateStatus.TryGetValue(vcam, out status)) { status = new UpdateStatus(now); mUpdateStatus.Add(vcam, status); } int subframes = isSmartLateUpdate ? 1 : CinemachineBrain.GetSubframeCount(); if (status.lastUpdateFrame != now) { status.lastUpdateSubframe = 0; } // If we're in smart update mode and the target moved, then we must examine // how the target has been moving recently in order to figure out whether to // update now bool updateNow = !isSmartUpdate; if (isSmartUpdate) { Matrix4x4 targetPos; if (!GetTargetPosition(vcam, out targetPos)) { updateNow = isSmartLateUpdate; // no target } else { updateNow = status.ChoosePreferredUpdate(now, targetPos, CurrentUpdateFilter) == CurrentUpdateFilter; } } if (updateNow) { status.preferredUpdate = CurrentUpdateFilter; while (status.lastUpdateSubframe < subframes) { //Debug.Log(vcam.Name + ": frame " + Time.frameCount + "." + status.lastUpdateSubframe + ", " + CurrentUpdateFilter); vcam.UpdateCameraState(worldUp, deltaTime); ++status.lastUpdateSubframe; } status.lastUpdateFrame = now; } mUpdateStatus[vcam] = status; //UnityEngine.Profiling.Profiler.EndSample(); return(true); }
/// <summary> /// Update a single Cinemachine Virtual Camera if and only if it /// hasn't already been updated this frame. Always update vcams via this method. /// Calling this more than once per frame for the same camera will have no effect. /// </summary> internal bool UpdateVirtualCamera(ICinemachineCamera vcam, Vector3 worldUp, float deltaTime) { if (mUpdateStatus == null) { mUpdateStatus = new Dictionary <ICinemachineCamera, UpdateStatus>(); } if (vcam.VirtualCameraGameObject == null) { if (mUpdateStatus.ContainsKey(vcam)) { mUpdateStatus.Remove(vcam); } return(false); // camera was deleted } UpdateStatus status = new UpdateStatus(); if (!mUpdateStatus.TryGetValue(vcam, out status)) { status.frame = -1; status.subframe = 0; status.lastFixedUpdate = -1; status.targetPos = Matrix4x4.zero; mUpdateStatus.Add(vcam, status); } int subframes = (CurrentUpdateFilter == UpdateFilter.Late) ? 1 : CinemachineBrain.GetSubframeCount(); int now = Time.frameCount; if (status.frame != now) { status.subframe = 0; } // If we're in smart update mode and the target moved, then we must update now bool updateNow = (CurrentUpdateFilter == UpdateFilter.Any); if (!updateNow) { Matrix4x4 targetPos; if (!GetTargetPosition(vcam, out targetPos)) { updateNow = CurrentUpdateFilter == UpdateFilter.Late; } else { if (status.targetPos != targetPos) { updateNow = true; } status.targetPos = targetPos; } } // If we haven't been updated in a couple of frames, better update now if (CurrentUpdateFilter == UpdateFilter.Late && status.lastFixedUpdate < now - 2) { updateNow = true; } if (updateNow) { while (status.subframe < subframes) { //Debug.Log(vcam.Name + ": frame " + Time.frameCount + "." + status.subframe + ", " + CurrentUpdateFilter); vcam.UpdateCameraState(worldUp, deltaTime); if (CurrentUpdateFilter == UpdateFilter.Fixed) { status.lastFixedUpdate = now; } ++status.subframe; } status.frame = now; } mUpdateStatus[vcam] = status; return(true); }
/// <summary> /// Update a single Cinemachine Virtual Camera if and only if it /// hasn't already been updated this frame. Always update vcams via this method. /// Calling this more than once per frame for the same camera will have no effect. /// </summary> internal bool UpdateVirtualCamera( CinemachineVirtualCameraBase vcam, Vector3 worldUp, float deltaTime) { UpdateFilter filter = CurrentUpdateFilter; bool isSmartUpdate = filter != UpdateFilter.ForcedFixed && filter != UpdateFilter.ForcedLate; bool isSmartLateUpdate = filter == UpdateFilter.Late; if (!isSmartUpdate) { if (filter == UpdateFilter.ForcedFixed) { filter = UpdateFilter.Fixed; } if (filter == UpdateFilter.ForcedLate) { filter = UpdateFilter.Late; } } if (mUpdateStatus == null) { mUpdateStatus = new Dictionary <CinemachineVirtualCameraBase, UpdateStatus>(); } if (vcam.gameObject == null) { if (mUpdateStatus.ContainsKey(vcam)) { mUpdateStatus.Remove(vcam); } return(false); // camera was deleted } int now = Time.frameCount; UpdateStatus status; if (!mUpdateStatus.TryGetValue(vcam, out status)) { status = new UpdateStatus(now); mUpdateStatus.Add(vcam, status); } int subframes = isSmartLateUpdate ? 1 : CinemachineBrain.GetSubframeCount(); if (status.lastUpdateFrame != now) { status.lastUpdateSubframe = 0; } // If we're in smart update mode and the target moved, then we must examine // how the target has been moving recently in order to figure out whether to // update now bool updateNow = !isSmartUpdate; if (isSmartUpdate) { Matrix4x4 targetPos; if (!GetTargetPosition(vcam, out targetPos)) { updateNow = isSmartLateUpdate; // no target } else { updateNow = status.ChoosePreferredUpdate(now, targetPos, filter) == filter; } } if (updateNow) { status.preferredUpdate = filter; while (status.lastUpdateSubframe < subframes) { //Debug.Log((vcam.ParentCamera == null ? "" : vcam.ParentCamera.Name + ".") + vcam.Name + ": frame " + Time.frameCount + "." + status.lastUpdateSubframe + ", " + CurrentUpdateFilter + ", deltaTime = " + deltaTime); vcam.InternalUpdateCameraState(worldUp, deltaTime); ++status.lastUpdateSubframe; } status.lastUpdateFrame = now; } mUpdateStatus[vcam] = status; return(updateNow); }
internal bool UpdateVirtualCamera(ICinemachineCamera vcam, Vector3 worldUp, float deltaTime) { int frameCount = Time.frameCount; CinemachineCore.UpdateFilter updateFilter = this.CurrentUpdateFilter; bool flag = updateFilter != CinemachineCore.UpdateFilter.ForcedFixed && updateFilter != CinemachineCore.UpdateFilter.ForcedLate; bool flag2 = updateFilter == CinemachineCore.UpdateFilter.Late; if (!flag) { if (updateFilter == CinemachineCore.UpdateFilter.ForcedFixed) { updateFilter = CinemachineCore.UpdateFilter.Fixed; } if (updateFilter == CinemachineCore.UpdateFilter.ForcedLate) { updateFilter = CinemachineCore.UpdateFilter.Late; } } if (this.mUpdateStatus == null) { this.mUpdateStatus = new Dictionary <ICinemachineCamera, CinemachineCore.UpdateStatus>(); } if (vcam.VirtualCameraGameObject == null) { if (this.mUpdateStatus.ContainsKey(vcam)) { this.mUpdateStatus.Remove(vcam); } return(false); } CinemachineCore.UpdateStatus updateStatus; if (!this.mUpdateStatus.TryGetValue(vcam, out updateStatus)) { updateStatus = new CinemachineCore.UpdateStatus(frameCount); this.mUpdateStatus.Add(vcam, updateStatus); } int num = flag2 ? 1 : CinemachineBrain.GetSubframeCount(); if (updateStatus.lastUpdateFrame != frameCount) { updateStatus.lastUpdateSubframe = 0; } bool flag3 = !flag; if (flag) { Matrix4x4 pos; if (!CinemachineCore.GetTargetPosition(vcam, out pos)) { flag3 = flag2; } else { flag3 = (updateStatus.ChoosePreferredUpdate(frameCount, pos, updateFilter) == updateFilter); } } if (flag3) { updateStatus.preferredUpdate = updateFilter; while (updateStatus.lastUpdateSubframe < num) { vcam.UpdateCameraState(worldUp, deltaTime); updateStatus.lastUpdateSubframe++; } updateStatus.lastUpdateFrame = frameCount; } this.mUpdateStatus[vcam] = updateStatus; return(true); }
/// <summary>Update all the active vcams in the scene, in the correct dependency order.</summary> internal void UpdateAllActiveVirtualCameras(int layerMask, Vector3 worldUp, float deltaTime) { bool isLateUpdate = CurrentUpdateFilter == UpdateFilter.Late || CurrentUpdateFilter == UpdateFilter.ForcedLate; bool canUpdateStandby = isLateUpdate || CinemachineBrain.GetSubframeCount() == 1; bool didRoundRobinUpdate = false; CinemachineVirtualCameraBase currentRoundRobin = mRoundRobinVcamLastFrame; // Update the leaf-most cameras first for (int i = mAllCameras.Count - 1; i >= 0; --i) { var sublist = mAllCameras[i]; for (int j = sublist.Count - 1; j >= 0; --j) { bool doRoundRobinUpdateNow = false; var vcam = sublist[j]; if (!IsLive(vcam)) { // Don't ever update subframes if not live if (!canUpdateStandby) { continue; } if (vcam.m_StandbyUpdate == CinemachineVirtualCameraBase.StandbyUpdateMode.Never) { continue; } if (!vcam.isActiveAndEnabled) { continue; } // Handle round-robin if (vcam.m_StandbyUpdate == CinemachineVirtualCameraBase.StandbyUpdateMode.RoundRobin) { if (currentRoundRobin != null) { if (currentRoundRobin == vcam) { currentRoundRobin = null; // Take the next vcam for round-robin } continue; } doRoundRobinUpdateNow = true; currentRoundRobin = vcam; } } // Unless this is a round-robin update, we skip this vcam if it's // not on the layer mask if (!doRoundRobinUpdateNow && ((1 << vcam.gameObject.layer) & layerMask) == 0) { continue; } bool updated = UpdateVirtualCamera(vcam, worldUp, deltaTime); if (canUpdateStandby && vcam == currentRoundRobin) { // Did the previous roundrobin go live this frame? if (!doRoundRobinUpdateNow) { currentRoundRobin = null; // yes, take the next vcam for round-robin } else if (updated) { didRoundRobinUpdate = true; } else { currentRoundRobin = mRoundRobinVcamLastFrame; // We tried to update but it didn't happen - keep the old one for next time } } } } // Finally, if the last roundrobin update candidate no longer exists, get rid of it if (canUpdateStandby && !didRoundRobinUpdate) { currentRoundRobin = null; // take the first vcam for next round-robin } mRoundRobinVcamLastFrame = currentRoundRobin; }