/// <summary> /// Update the X axis and calculate the heading. This can be called by a delegate /// with a custom axis. /// <param name="deltaTime">Used for damping. If less than 0, no damping is done.</param> /// <param name="up">World Up, set by the CinemachineBrain</param> /// <param name="axis"></param> /// <param name="recentering"></param> /// <param name="isLive"/>true if the vcam is live</param> /// <returns>Axis value</returns> /// </summary> public float UpdateHeading( float deltaTime, Vector3 up, ref AxisState axis, ref AxisState.Recentering recentering, bool isLive) { // Only read joystick when game is playing if (deltaTime < 0 || !isLive) { axis.Reset(); recentering.CancelRecentering(); } else if (axis.Update(deltaTime)) { recentering.CancelRecentering(); } float targetHeading = GetTargetHeading(axis.Value, GetReferenceOrientation(up), deltaTime); if (deltaTime >= 0 && m_BindingMode != BindingMode.SimpleFollowWithWorldUp) { recentering.DoRecentering(ref axis, deltaTime, targetHeading); } float finalHeading = axis.Value; if (m_BindingMode == BindingMode.SimpleFollowWithWorldUp) { axis.Value = 0; } return(finalHeading); }
/// <summary> /// Update the X axis and calculate the heading. This can be called by a delegate /// with a custom axis. /// <param name="deltaTime">Used for damping. If less than 0, no damping is done.</param> /// <param name="up">World Up, set by the CinemachineBrain</param> /// <param name="axis"></param> /// <returns>Axis value</returns> /// </summary> public float UpdateHeading(float deltaTime, Vector3 up, ref AxisState axis) { // Only read joystick when game is playing if (deltaTime < 0 || !CinemachineCore.Instance.IsLive(VirtualCamera)) { axis.Reset(); m_RecenterToTargetHeading.CancelRecentering(); } else if (axis.Update(deltaTime)) { m_RecenterToTargetHeading.CancelRecentering(); } float targetHeading = GetTargetHeading(axis.Value, GetReferenceOrientation(up), deltaTime); if (m_BindingMode != BindingMode.SimpleFollowWithWorldUp) { m_RecenterToTargetHeading.DoRecentering(ref axis, deltaTime, targetHeading); } float finalHeading = axis.Value; if (m_BindingMode == BindingMode.SimpleFollowWithWorldUp) { axis.Value = 0; } return(finalHeading); }
/// <summary>Applies the axis values and orients the camera accordingly</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for calculating damping. Not used.</param> public override void MutateCameraState(ref CameraState curState, float deltaTime) { if (!IsValid) { return; } // Only read joystick when game is playing if (deltaTime >= 0 || CinemachineCore.Instance.IsLive(VirtualCamera)) { if (m_HorizontalAxis.Update(deltaTime)) { m_HorizontalRecentering.CancelRecentering(); } if (m_VerticalAxis.Update(deltaTime)) { m_VerticalRecentering.CancelRecentering(); } } m_HorizontalRecentering.DoRecentering(ref m_HorizontalAxis, deltaTime, 0); m_VerticalRecentering.DoRecentering(ref m_VerticalAxis, deltaTime, 0); Quaternion rot = Quaternion.Euler(m_VerticalAxis.Value, m_HorizontalAxis.Value, 0); rot = rot * Quaternion.FromToRotation(Vector3.up, curState.ReferenceUp); curState.RawOrientation = rot; }
/// <summary>Internal use only. Called by CinemachineCore at designated update time /// so the vcam can position itself and track its targets. All 3 child rigs are updated, /// and a blend calculated, depending on the value of the Y axis.</summary> /// <param name="worldUp">Default world Up, set by the CinemachineBrain</param> /// <param name="deltaTime">Delta time for time-based effects (ignore if less than 0)</param> override public void InternalUpdateCameraState(Vector3 worldUp, float deltaTime) { UpdateRigCache(); // Update the current state by invoking the component pipeline Vector3 prePos = m_State.FinalPosition; m_State = CalculateNewState(worldUp, deltaTime, prePos); m_State.PreviousPosition = prePos; ApplyPositionBlendMethod(ref m_State, m_Transitions.m_BlendHint); // Push the raw position back to the game object's transform, so it // moves along with the camera. Leave the orientation alone, because it // screws up camera dragging when there is a LookAt behaviour. if (Follow != null) { Vector3 delta = State.RawPosition - transform.position; transform.position = State.RawPosition; m_Rigs[0].transform.position -= delta; m_Rigs[1].transform.position -= delta; m_Rigs[2].transform.position -= delta; } if (!m_ChildExecuteExtension) { CinemachineCore.Stage curStage = CinemachineCore.Stage.Body; while ((int)curStage < (int)CinemachineCore.Stage.Finalize + 1) { InvokePostPipelineStageCallback(this, curStage, ref m_State, deltaTime); ++curStage; } } else { InvokePostPipelineStageCallback(this, CinemachineCore.Stage.Finalize, ref m_State, deltaTime); } PreviousStateIsValid = true; // Set up for next frame bool activeCam = PreviousStateIsValid && CinemachineCore.Instance.IsLive(this); if (activeCam && deltaTime >= 0) { if (m_YAxis.Update(deltaTime)) { m_YAxisRecentering.CancelRecentering(); } } PushSettingsToRigs(); if (m_BindingMode == CinemachineTransposer.BindingMode.SimpleFollowWithWorldUp) { m_XAxis.Value = 0; } }
/// <summary>If we are transitioning from another FreeLook, grab the axis values from it.</summary> /// <param name="fromCam">The camera being deactivated. May be null.</param> /// <param name="worldUp">Default world Up, set by the CinemachineBrain</param> /// <param name="deltaTime">Delta time for time-based effects (ignore if less than or equal to 0)</param> public override void OnTransitionFromCamera( ICinemachineCamera fromCam, Vector3 worldUp, float deltaTime) { base.OnTransitionFromCamera(fromCam, worldUp, deltaTime); InvokeOnTransitionInExtensions(fromCam, worldUp, deltaTime); bool forceUpdate = false; m_RecenterToTargetHeading.DoRecentering(ref m_XAxis, -1, 0); m_RecenterToTargetHeading.DoRecentering(ref m_YAxis, -1, 0.5f); m_RecenterToTargetHeading.CancelRecentering(); m_YAxis.m_Recentering.CancelRecentering(); if (fromCam != null && m_Transitions.m_InheritPosition) { var cameraPos = fromCam.State.RawPosition; // Special handling for FreeLook: get an undamped outgoing position if (fromCam is CinemachineFreeLook) { var flFrom = (fromCam as CinemachineFreeLook); var orbital = flFrom.mOrbitals != null ? flFrom.mOrbitals[1] : null; if (orbital != null) { cameraPos = orbital.GetTargetCameraPosition(worldUp); } } UpdateRigCache(); if (m_BindingMode != CinemachineTransposer.BindingMode.SimpleFollowWithWorldUp) { m_XAxis.Value = mOrbitals[1].GetAxisClosestValue(cameraPos, worldUp); } m_YAxis.Value = GetYAxisClosestValue(cameraPos, worldUp); transform.position = cameraPos; transform.rotation = fromCam.State.RawOrientation; m_State = PullStateFromVirtualCamera(worldUp, ref m_Lens); PreviousStateIsValid = false; PushSettingsToRigs(); forceUpdate = true; } if (forceUpdate) { InternalUpdateCameraState(worldUp, deltaTime); } else { UpdateCameraState(worldUp, deltaTime); } if (m_Transitions.m_OnCameraLive != null) { m_Transitions.m_OnCameraLive.Invoke(this, fromCam); } }
/// <summary>Internal use only. Called by CinemachineCore at designated update time /// so the vcam can position itself and track its targets. All 3 child rigs are updated, /// and a blend calculated, depending on the value of the Y axis.</summary> /// <param name="worldUp">Default world Up, set by the CinemachineBrain</param> /// <param name="deltaTime">Delta time for time-based effects (ignore if less than 0)</param> override public void InternalUpdateCameraState(Vector3 worldUp, float deltaTime) { //UnityEngine.Profiling.Profiler.BeginSample("CinemachineFreeLook.InternalUpdateCameraState"); if (!PreviousStateIsValid) { deltaTime = -1; } UpdateRigCache(); // Reset the base camera state, in case the game object got moved in the editor if (deltaTime < 0) { m_State = PullStateFromVirtualCamera(worldUp); // Not in gameplay } // Update the current state by invoking the component pipeline m_State = CalculateNewState(worldUp, deltaTime); SetPositionBlendMethod(ref m_State, m_PositionBlending); // Push the raw position back to the game object's transform, so it // moves along with the camera. Leave the orientation alone, because it // screws up camera dragging when there is a LookAt behaviour. if (Follow != null) { Vector3 delta = State.RawPosition - transform.position; transform.position = State.RawPosition; m_Rigs[0].transform.position -= delta; m_Rigs[1].transform.position -= delta; m_Rigs[2].transform.position -= delta; } InvokePostPipelineStageCallback(this, CinemachineCore.Stage.Finalize, ref m_State, deltaTime); PreviousStateIsValid = true; // Set up for next frame bool activeCam = (deltaTime >= 0) || CinemachineCore.Instance.IsLive(this); if (activeCam) { if (m_YAxis.Update(deltaTime)) { m_YAxisRecentering.CancelRecentering(); } } PushSettingsToRigs(); //UnityEngine.Profiling.Profiler.EndSample(); }
/// <summary>Internal use only. Called by CinemachineCore at designated update time /// so the vcam can position itself and track its targets. All 3 child rigs are updated, /// and a blend calculated, depending on the value of the Y axis.</summary> /// <param name="worldUp">Default world Up, set by the CinemachineBrain</param> /// <param name="deltaTime">Delta time for time-based effects (ignore if less than 0)</param> override public void InternalUpdateCameraState(Vector3 worldUp, float deltaTime) { if (!PreviousStateIsValid) { deltaTime = -1; } UpdateRigCache(); // Update the current state by invoking the component pipeline m_State = CalculateNewState(worldUp, deltaTime); ApplyPositionBlendMethod(ref m_State, m_Transitions.m_BlendHint); // Push the raw position back to the game object's transform, so it // moves along with the camera. Leave the orientation alone, because it // screws up camera dragging when there is a LookAt behaviour. if (Follow != null) { Vector3 delta = State.RawPosition - transform.position; transform.position = State.RawPosition; m_Rigs[0].transform.position -= delta; m_Rigs[1].transform.position -= delta; m_Rigs[2].transform.position -= delta; } InvokePostPipelineStageCallback(this, CinemachineCore.Stage.Finalize, ref m_State, deltaTime); PreviousStateIsValid = true; // Set up for next frame bool activeCam = (deltaTime >= 0) && CinemachineCore.Instance.IsLive(this); if (activeCam) { if (m_YAxis.Update(deltaTime)) { m_YAxisRecentering.CancelRecentering(); } } PushSettingsToRigs(); }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == m_ApplyAfter) { // Only read joystick when game is playing if (m_UpdateAlways || (deltaTime >= 0 && CinemachineCore.Instance.IsLive(VirtualCamera))) { bool changed = m_HorizontalInput.Update(deltaTime, ref m_HorizontalAxis); if (m_VerticalInput.Update(deltaTime, ref m_VerticalAxis)) { changed = true; } if (changed) { m_HorizontalRecentering.CancelRecentering(); m_VerticalRecentering.CancelRecentering(); } } m_HorizontalAxis.m_Value = m_HorizontalRecentering.DoRecentering(m_HorizontalAxis.m_Value, deltaTime, 0); m_VerticalAxis.m_Value = m_VerticalRecentering.DoRecentering(m_VerticalAxis.m_Value, deltaTime, 0); // If we have a transform parent, then apply POV in the local space of the parent Quaternion rot = Quaternion.Euler(m_VerticalAxis.m_Value, m_HorizontalAxis.m_Value, 0); Transform parent = VirtualCamera.transform.parent; if (parent != null) { rot = parent.rotation * rot; } else { rot = rot * Quaternion.FromToRotation(Vector3.up, state.ReferenceUp); } state.RawOrientation = rot; } }