public UpdateStatus() { lastUpdateFrame = -2; lastUpdateFixedFrame = 0; lastUpdateMode = UpdateTracker.UpdateClock.Late; lastUpdateDeltaTime = -2; }
/// <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 void UpdateVirtualCamera( CinemachineVirtualCameraBase vcam, Vector3 worldUp, float deltaTime) { if (vcam == null) { return; } bool isSmartUpdate = (CurrentUpdateFilter & UpdateFilter.Smart) == UpdateFilter.Smart; UpdateTracker.UpdateClock updateClock = (UpdateTracker.UpdateClock)(CurrentUpdateFilter & ~UpdateFilter.Smart); // 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 if (isSmartUpdate) { Transform updateTarget = GetUpdateTarget(vcam); if (updateTarget == null) { return; // vcam deleted } if (UpdateTracker.GetPreferredUpdate(updateTarget) != updateClock) { return; // wrong clock } } // Have we already been updated this frame? if (mUpdateStatus == null) { mUpdateStatus = new Dictionary <CinemachineVirtualCameraBase, UpdateStatus>(); } UpdateStatus status; if (!mUpdateStatus.TryGetValue(vcam, out status)) { status = new UpdateStatus(); mUpdateStatus.Add(vcam, status); } int frameDelta = (updateClock == UpdateTracker.UpdateClock.Late) ? Time.frameCount - status.lastUpdateFrame : FixedFrameCount - status.lastUpdateFixedFrame; if (deltaTime >= 0 && frameDelta == 0 && status.lastUpdateMode == updateClock) { return; // already updated } if (frameDelta != 1) { deltaTime = -1; // multiple frames - kill the damping } //Debug.Log((vcam.ParentCamera == null ? "" : vcam.ParentCamera.Name + ".") + vcam.Name + ": frame " + Time.frameCount + "/" + status.lastUpdateFixedFrame + ", " + CurrentUpdateFilter + ", deltaTime = " + deltaTime); vcam.InternalUpdateCameraState(worldUp, deltaTime); status.lastUpdateFrame = Time.frameCount; status.lastUpdateFixedFrame = FixedFrameCount; status.lastUpdateMode = updateClock; }
protected void DrawCameraStatusInInspector() { // Is the camera navel-gazing? CameraState state = Target.State; if (state.HasLookAt && (state.ReferenceLookAt - state.CorrectedPosition).AlmostZero()) { EditorGUILayout.HelpBox( "The camera is positioned on the same point at which it is trying to look.", MessageType.Warning); } // Active status and Solo button Rect rect = EditorGUILayout.GetControlRect(true); Rect rectLabel = new Rect(rect.x, rect.y, EditorGUIUtility.labelWidth, rect.height); rect.width -= rectLabel.width; rect.x += rectLabel.width; Color color = GUI.color; bool isSolo = (CinemachineBrain.SoloCamera == (ICinemachineCamera)Target); if (isSolo) { GUI.color = CinemachineBrain.GetSoloGUIColor(); } bool isLive = CinemachineCore.Instance.IsLive(Target); GUI.enabled = isLive; GUI.Label(rectLabel, isLive ? "Status: Live" : (Target.isActiveAndEnabled ? "Status: Standby" : "Status: Disabled")); GUI.enabled = true; float labelWidth = 0; GUIContent updateText = GUIContent.none; UpdateTracker.UpdateClock updateMode = CinemachineCore.Instance.GetVcamUpdateStatus(Target); if (Application.isPlaying) { updateText = new GUIContent( updateMode == UpdateTracker.UpdateClock.Fixed ? " Fixed Update" : " Late Update"); var textDimensions = GUI.skin.label.CalcSize(updateText); labelWidth = textDimensions.x; } rect.width -= labelWidth; if (GUI.Button(rect, "Solo", "Button")) { isSolo = !isSolo; CinemachineBrain.SoloCamera = isSolo ? Target : null; #if UNITY_2019_1_OR_NEWER EditorUtility.SetDirty(Target); #else UnityEditorInternal.InternalEditorUtility.RepaintAllViews(); #endif } GUI.color = color; if (isSolo && !Application.isPlaying) { InspectorUtility.RepaintGameView(Target); } if (labelWidth > 0) { GUI.enabled = false; rect.x += rect.width; rect.width = labelWidth; GUI.Label(rect, updateText); GUI.enabled = true; } }