private void Update() { #region recoil //isAiming = Input.GetMouseButton(1); animator.SetBool(isAimingParam, isAiming); var weapon = activeWeapon.GetActiveWeapon(); if (weapon) { weapon.recoil.recoilModifier = isAiming ? 0.3f : 1.0f; } #endregion if (desktopControlls.DesktopControlls) { //Debug.Log(desktopControlls.DesktopControlls); #region Camera Aiming Desktop xAxis.Update(Time.fixedDeltaTime); yAxis.Update(Time.fixedDeltaTime); cameraLookAt.eulerAngles = new Vector3(yAxis.Value, xAxis.Value, 0); //Rotation of camera in Y axis float yawCamera = mainCamera.transform.rotation.eulerAngles.y; //Blend from current rotation towards the cams rotatiion only in y axis transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, yawCamera, 0), turnSpeed * Time.fixedDeltaTime); #endregion } else { #region MOBILE AIMING CODE WORKING if (Input.touchCount > 0) { if ((Input.touches[0].position.x > Screen.width / 2 && Input.touches[0].phase == TouchPhase.Moved) || (Input.touches[1].position.x > Screen.width / 2 && Input.touches[1].phase == TouchPhase.Moved)) { #region TESTING CODE 5 xAxis.Update(Time.fixedDeltaTime); yAxis.Update(Time.fixedDeltaTime); cameraLookAt.eulerAngles = new Vector3(yAxis.Value, xAxis.Value, 0); //Rotation of camera in Y axis float yawCamera = mainCamera.transform.rotation.eulerAngles.y; //Blend from current rotation towards the cams rotatiion only in y axis transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, yawCamera, 0), turnSpeed * Time.fixedDeltaTime); #endregion } } #endregion } }
/// <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> /// 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>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(); var recenterTarget = GetRecenterTarget(); m_HorizontalRecentering.DoRecentering(ref m_HorizontalAxis, deltaTime, recenterTarget.x); m_VerticalRecentering.DoRecentering(ref m_VerticalAxis, deltaTime, recenterTarget.y); } // If we have a transform parent, then apply POV in the local space of the parent Quaternion rot = Quaternion.Euler(m_VerticalAxis.Value, m_HorizontalAxis.Value, 0); Transform parent = VirtualCamera.transform.parent; if (parent != null) rot = parent.rotation * rot; else rot = rot * Quaternion.FromToRotation(Vector3.up, curState.ReferenceUp); curState.RawOrientation = rot; }
public float UpdateHeading(float deltaTime, Vector3 up, ref AxisState axis) { if (deltaTime >= 0f || CinemachineCore.Instance.IsLive(base.VirtualCamera)) { bool flag = false; flag |= axis.Update(deltaTime); if (flag) { this.mLastHeadingAxisInputTime = Time.time; this.mHeadingRecenteringVelocity = 0f; } } float targetHeading = this.GetTargetHeading(axis.Value, base.GetReferenceOrientation(up), deltaTime); if (deltaTime < 0f) { this.mHeadingRecenteringVelocity = 0f; if (this.m_RecenterToTargetHeading.m_enabled) { axis.Value = targetHeading; } } else if (this.m_BindingMode != CinemachineTransposer.BindingMode.SimpleFollowWithWorldUp && this.m_RecenterToTargetHeading.m_enabled && Time.time > this.mLastHeadingAxisInputTime + this.m_RecenterToTargetHeading.m_RecenterWaitTime) { float num = this.m_RecenterToTargetHeading.m_RecenteringTime / 3f; if (num <= deltaTime) { axis.Value = targetHeading; } else { float f = Mathf.DeltaAngle(axis.Value, targetHeading); float num2 = Mathf.Abs(f); if (num2 < 0.0001f) { axis.Value = targetHeading; this.mHeadingRecenteringVelocity = 0f; } else { float num3 = deltaTime / num; float num4 = Mathf.Sign(f) * Mathf.Min(num2, num2 * num3); float num5 = num4 - this.mHeadingRecenteringVelocity; if ((num4 < 0f && num5 < 0f) || (num4 > 0f && num5 > 0f)) { num4 = this.mHeadingRecenteringVelocity + num4 * num3; } axis.Value += num4; this.mHeadingRecenteringVelocity = num4; } } } float value = axis.Value; if (this.m_BindingMode == CinemachineTransposer.BindingMode.SimpleFollowWithWorldUp) { axis.Value = 0f; } return(value); }
private void Update() { isAiming = Input.GetMouseButton(1); animator.SetBool(isAimingParam, isAiming); var weapon = activeWeapon.GetActiveWeapon(); if (weapon) { weapon.recoil.recoilModifier = isAiming ? 0.3f : 1.0f; } xAxis.Update(Time.fixedDeltaTime); yAxis.Update(Time.fixedDeltaTime); float max = yAxis.m_MaxValue = 90; float min = yAxis.m_MinValue = -90; cameraLookAt.eulerAngles = new Vector3(Mathf.Clamp(yAxis.Value, min, max), xAxis.Value, 0); //Rotation of camera in Y axis float yawCamera = mainCamera.transform.rotation.eulerAngles.y; //Blend from current rotation towards the cams rotatiion only in y axis transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, yawCamera, 0), turnSpeed * Time.fixedDeltaTime); }
/// <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) { if (m_BindingMode == BindingMode.SimpleFollowWithWorldUp) { axis.m_MinValue = -180; axis.m_MaxValue = 180; } // Only read joystick when game is playing if (deltaTime < 0 || !VirtualCamera.PreviousStateIsValid || !isLive) { axis.Reset(); recentering.CancelRecentering(); } else if (axis.Update(deltaTime)) { recentering.CancelRecentering(); } if (m_BindingMode == BindingMode.SimpleFollowWithWorldUp) { float finalHeading = axis.Value; axis.Value = 0; return(finalHeading); } float targetHeading = GetTargetHeading(axis.Value, GetReferenceOrientation(up)); recentering.DoRecentering(ref axis, deltaTime, targetHeading); return(axis.Value); }
/// <summary> /// This is called prior to the updating of the vcam's child cameras, /// in order to allow the parent to prepare its children. /// If the children are updating on FixedUpdate, then this will not necessarily be called /// prior to every FixedUpdate, but might be called on LateUpdate. /// This implementation pushes the axis values to the rigs. /// </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 PreUpdateChildCameras(Vector3 worldUp, float deltaTime) { //UnityEngine.Profiling.Profiler.BeginSample("CinemachineFreeLook.PreUpdateChildCameras"); if (!PreviousStateIsValid) { deltaTime = -1; } UpdateRigCache(); // Read the Height bool activeCam = (deltaTime >= 0) || CinemachineCore.Instance.IsLive(this); if (activeCam) { m_YAxis.Update(deltaTime); } // Read the heading. Make sure all the rigs get updated first PushSettingsToRigs(); if (activeCam) { UpdateHeading(deltaTime, m_State.ReferenceUp); } //UnityEngine.Profiling.Profiler.EndSample(); }
/// <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); }
void Awake() { #if false // make this true for CM 2.1.10 and earlier, false otherwise zAxis.SetThresholds(0, 1, false); #endif freelook = GetComponentInChildren <CinemachineFreeLook>(); if (freelook != null && originalOrbits.Length == 0) { zAxis.Update(Time.deltaTime); float scale = Mathf.Lerp(minScale, maxScale, zAxis.Value); for (int i = 0; i < Mathf.Min(originalOrbits.Length, freelook.m_Orbits.Length); i++) { freelook.m_Orbits[i].m_Height = originalOrbits[i].m_Height * scale; freelook.m_Orbits[i].m_Radius = originalOrbits[i].m_Radius * scale; } } }
private void FixedUpdate() { xAxis.Update(Time.fixedDeltaTime); yAxis.Update(Time.fixedDeltaTime); cameraLookAt.eulerAngles = new Vector3(yAxis.Value, xAxis.Value, 0); float yawCamera = mainCamera.transform.rotation.eulerAngles.y; transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, yawCamera, 0), turnSpeed * Time.deltaTime); }
/// <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; } }
// Update is called once per frame void FixedUpdate() { xAxis.Update(Time.fixedDeltaTime); yAxis.Update(Time.fixedDeltaTime); followTarget.eulerAngles = new Vector3(yAxis.Value, xAxis.Value, 0); float yAngle = mainCamera.transform.rotation.eulerAngles.y; transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, yAngle, 0), turnSpeed.y * Time.fixedDeltaTime); }
// Update is called once per frame void FixedUpdate() { xAxis.Update(Time.fixedDeltaTime); yAxis.Update(Time.fixedDeltaTime); cameraLookAt.eulerAngles = new Vector3(yAxis.Value, xAxis.Value, 0); if (!Input.GetKey(KeyCode.LeftAlt)) { RotatingPlayerToCameraView(); } }
/// <summary>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 UpdateCameraState(Vector3 worldUp, float deltaTime) { //UnityEngine.Profiling.Profiler.BeginSample("CinemachineFreeLook.UpdateCameraState"); if (!PreviousStateIsValid) { deltaTime = -1; } UpdateRigCache(); // Read the Height bool activeCam = (deltaTime >= 0) || CinemachineCore.Instance.IsLive(this); if (activeCam) { m_YAxis.Update(deltaTime); } // Reads the heading. Make sure all the rigs get updated first PushSettingsToRigs(); if (activeCam) { UpdateHeading(deltaTime, m_State.ReferenceUp); } // Drive the rigs for (int i = 0; i < m_Rigs.Length; ++i) { if (m_Rigs[i] != null) { CinemachineCore.Instance.UpdateVirtualCamera(m_Rigs[i], worldUp, deltaTime); } } // 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); // 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) { transform.position = State.RawPosition; } PreviousStateIsValid = true; //UnityEngine.Profiling.Profiler.EndSample(); }
void Update() { if (originalOrbits != null) { zAxis.Update(Time.deltaTime); float scale = Mathf.Lerp(minScale, maxScale, zAxis.Value); for (int i = 0; i < originalOrbits.Length; i++) { freelook.m_Orbits[i].m_Height = originalOrbits[i].m_Height * scale; freelook.m_Orbits[i].m_Radius = originalOrbits[i].m_Radius * scale; } } }
/// <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>Applies the composer rules and orients the camera accordingly</summary> /// <param name="curState">The current camera state</param> /// <param name="deltaTime">Used for calculating damping. If less than /// or equal to zero, then target will snap to the center of the dead zone.</param> public virtual void MutateCameraState(ref CameraState curState, float deltaTime) { if (!IsValid) { return; } //UnityEngine.Profiling.Profiler.BeginSample("CinemachinePOV.MutateCameraState"); // Only read joystick when game is playing if (deltaTime > 0 || CinemachineCore.Instance.IsLive(VirtualCamera)) { m_HorizontalAxis.Update(deltaTime); m_VerticalAxis.Update(deltaTime); } curState.OrientationCorrection = curState.OrientationCorrection * Quaternion.Euler(m_VerticalAxis.Value, m_HorizontalAxis.Value, 0); //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(); }
void Update() { if (originalOrbits != null) { zAxis.Update(Time.deltaTime); if (Input.touchCount == 2) { Touch touchZero = Input.GetTouch(0); Touch touchOne = Input.GetTouch(1); // Find the position in the previous frame of each touch. Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition; Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition; // Find the magnitude of the vector (the distance) between the touches in each frame. float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude; float touchDeltaMag = (touchZero.position - touchOne.position).magnitude; // Find the difference in the distances between each frame. float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag; scale = Mathf.Lerp(scale, scale + deltaMagnitudeDiff / 8f * Time.deltaTime, Time.deltaTime * 5f); scale = Mathf.Clamp(scale, minScale, maxScale); } else { #if !UNITY_IOS Debug.Log($"Z Axis is {zAxis.Value}"); scale = Mathf.Lerp(minScale, maxScale, zAxis.Value); #endif } //Debug.LogError($"Scale is {scale}"); for (int i = 0; i < originalOrbits.Length; i++) { freelook.m_Orbits[i].m_Height = originalOrbits[i].m_Height * scale; freelook.m_Orbits[i].m_Radius = originalOrbits[i].m_Radius * scale; } } }
/// <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; } //UnityEngine.Profiling.Profiler.BeginSample("CinemachinePOV.MutateCameraState"); // Only read joystick when game is playing if (deltaTime >= 0 || CinemachineCore.Instance.IsLive(VirtualCamera)) { m_HorizontalAxis.Update(deltaTime); m_VerticalAxis.Update(deltaTime); } Quaternion rot = Quaternion.Euler(m_VerticalAxis.Value, m_HorizontalAxis.Value, 0); rot = rot * Quaternion.FromToRotation(Vector3.up, curState.ReferenceUp); curState.OrientationCorrection = curState.OrientationCorrection * rot; //UnityEngine.Profiling.Profiler.EndSample(); }
/// <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)) { bool xAxisInput = false; xAxisInput |= axis.Update(deltaTime); if (xAxisInput) { mLastHeadingAxisInputTime = Time.time; mHeadingRecenteringVelocity = 0; } } float targetHeading = GetTargetHeading(axis.Value, GetReferenceOrientation(up), deltaTime); if (deltaTime < 0) { mHeadingRecenteringVelocity = 0; if (m_RecenterToTargetHeading.m_enabled) { axis.Value = targetHeading; } } else { // Recentering if (m_BindingMode != BindingMode.SimpleFollowWithWorldUp && m_RecenterToTargetHeading.m_enabled && (Time.time > (mLastHeadingAxisInputTime + m_RecenterToTargetHeading.m_RecenterWaitTime))) { // Scale value determined heuristically, to account for accel/decel float recenterTime = m_RecenterToTargetHeading.m_RecenteringTime / 3f; if (recenterTime <= deltaTime) { axis.Value = targetHeading; } else { float headingError = Mathf.DeltaAngle(axis.Value, targetHeading); float absHeadingError = Mathf.Abs(headingError); if (absHeadingError < UnityVectorExtensions.Epsilon) { axis.Value = targetHeading; mHeadingRecenteringVelocity = 0; } else { float scale = deltaTime / recenterTime; float desiredVelocity = Mathf.Sign(headingError) * Mathf.Min(absHeadingError, absHeadingError * scale); // Accelerate to the desired velocity float accel = desiredVelocity - mHeadingRecenteringVelocity; if ((desiredVelocity < 0 && accel < 0) || (desiredVelocity > 0 && accel > 0)) { desiredVelocity = mHeadingRecenteringVelocity + desiredVelocity * scale; } axis.Value += desiredVelocity; mHeadingRecenteringVelocity = desiredVelocity; } } } } float finalHeading = axis.Value; if (m_BindingMode == BindingMode.SimpleFollowWithWorldUp) { axis.Value = 0; } return(finalHeading); }