/// <summary>Callback to to the camera confining</summary> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { // Move the body before the Aim is calculated if (stage == CinemachineCore.Stage.Body) { UpdateBounds(); if (vcam.Follow != null) { vcam.Follow.position = GetFinalPosition(); } LensSettings newLensSettings = state.Lens; newLensSettings.OrthographicSize = GetFinalOrthographicSize(); state.Lens = newLensSettings; } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Body) { var pos = state.RawPosition; if (ignoreX) { pos.x = initialXPosition; } if (ignoreY) { pos.y = initialYPosition; } state.RawPosition = pos; } }
/// <summary>Callback to display the image</summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="stage">The current pipeline stage</param> /// <param name="state">The current virtual camera state</param> /// <param name="deltaTime">The current applicable deltaTime</param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { // Apply to this vcam only, not the children if (vcam != VirtualCamera || stage != CinemachineCore.Stage.Finalize) { return; } if (m_ShowImage) { state.AddCustomBlendable(new CameraState.CustomBlendable(this, 1)); } if (m_MuteCamera) { state.BlendHint |= CameraState.BlendHintValue.NoTransform | CameraState.BlendHintValue.NoLens; } }
/// <summary> /// Sets the ReferenceLookAt to be the result of a raycast in the direction of camera forward. /// If an object is hit, point is placed there, else it is placed at AimDistance. /// </summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="stage">The current pipeline stage</param> /// <param name="state">The current virtual camera state</param> /// <param name="deltaTime">The current applicable deltaTime</param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Body) { // Raycast to establish what we're actually aiming at state.ReferenceLookAt = GetLookAtPoint(ref state); } if (stage == CinemachineCore.Stage.Finalize) { var dir = state.ReferenceLookAt - state.FinalPosition; if (dir.sqrMagnitude > 0.01f) { state.RawOrientation = Quaternion.LookRotation(dir, state.ReferenceUp); state.OrientationCorrection = Quaternion.identity; } } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { VcamExtraState extra = GetExtraState <VcamExtraState>(vcam); if (!enabled || deltaTime < 0) { extra.m_previousFrameZoom = state.Lens.FieldOfView; } if (enabled) { // Set the zoom after the body has been positioned, but before the aim, // so that composer can compose using the updated fov. if (stage == CinemachineCore.Stage.Body) { // Try to reproduce the target width float targetWidth = Mathf.Max(m_Width, 0); float fov = 179f; float d = Vector3.Distance(state.CorrectedPosition, state.ReferenceLookAt); if (d > UnityVectorExtensions.Epsilon) { // Clamp targetWidth to FOV min/max float minW = d * 2f * Mathf.Tan(m_MinFOV * Mathf.Deg2Rad / 2f); float maxW = d * 2f * Mathf.Tan(m_MaxFOV * Mathf.Deg2Rad / 2f); targetWidth = Mathf.Clamp(targetWidth, minW, maxW); // Apply damping if (deltaTime >= 0 && m_Damping > 0) { float currentWidth = d * 2f * Mathf.Tan(extra.m_previousFrameZoom * Mathf.Deg2Rad / 2f); float delta = targetWidth - currentWidth; delta = Damper.Damp(delta, m_Damping, deltaTime); targetWidth = currentWidth + delta; } fov = 2f * Mathf.Atan(targetWidth / (2 * d)) * Mathf.Rad2Deg; } LensSettings lens = state.Lens; lens.FieldOfView = extra.m_previousFrameZoom = Mathf.Clamp(fov, m_MinFOV, m_MaxFOV); state.Lens = lens; } } }
bool StageIsLocked(CinemachineCore.Stage stage) { if (IsPrefab) { return(true); } CinemachineCore.Stage[] locked = Target.m_LockStageInInspector; if (locked != null) { for (int i = 0; i < locked.Length; ++i) { if (locked[i] == stage) { return(true); } } } return(false); }
void UpdateStageState(CinemachineComponentBase[] components) { m_stageState = new int[Enum.GetValues(typeof(CinemachineCore.Stage)).Length]; m_stageError = new bool[Enum.GetValues(typeof(CinemachineCore.Stage)).Length]; foreach (var c in components) { CinemachineCore.Stage stage = c.Stage; int index = 0; for (index = sStageData[(int)stage].types.Length - 1; index > 0; --index) { if (sStageData[(int)stage].types[index] == c.GetType()) { break; } } m_stageState[(int)stage] = index; m_stageError[(int)stage] = c == null || !c.IsValid; } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (enabled) { if (stage == CinemachineCore.Stage.Body) { VcamExtraState extra = GetExtraState <VcamExtraState>(vcam); if (m_PositionSmoothing > 0) { if (deltaTime < 0) { extra.mSmoothingFilter = null; // reset the filter } state.PositionCorrection += ApplySmoothing(vcam, state.CorrectedPosition, extra) - state.CorrectedPosition; } if (m_LookAtSmoothing > 0 && state.HasLookAt) { if (deltaTime < 0) { extra.mSmoothingFilterLookAt = null; // reset the filter } state.ReferenceLookAt = ApplySmoothingLookAt(vcam, state.ReferenceLookAt, extra); } } if (stage == CinemachineCore.Stage.Aim) { if (m_RotationSmoothing > 0) { VcamExtraState extra = GetExtraState <VcamExtraState>(vcam); if (deltaTime < 0) { extra.mSmoothingFilterRotation = null; // reset the filter } Quaternion q = Quaternion.Inverse(state.CorrectedOrientation) * ApplySmoothing(vcam, state.CorrectedOrientation, state.ReferenceUp, extra); state.OrientationCorrection = state.OrientationCorrection * q; } } } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { // Set the focus after the camera has been fully positioned. // GML todo: what about collider? if (stage == CinemachineCore.Stage.Aim) { if (!IsValid) { DestroyProfileCopy(); } else { // Handle Follow Focus if (!m_FocusTracksTarget) { DestroyProfileCopy(); } else { if (mProfileCopy == null || mCachedProfileIsInvalid) { CreateProfileCopy(); } DepthOfField dof; if (m_Profile.TryGet(out dof)) { float focusDistance = m_FocusOffset; if (state.HasLookAt) { focusDistance += (state.FinalPosition - state.ReferenceLookAt).magnitude; } dof.focusDistance.value = Mathf.Max(0, focusDistance); } } // Apply the post-processing state.AddCustomBlendable(new CameraState.CustomBlendable(this, 1)); } } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == m_ApplyAfter) { bool preserveAim = m_PreserveComposition && state.HasLookAt && stage > CinemachineCore.Stage.Body; Vector3 screenOffset = Vector2.zero; if (preserveAim) { screenOffset = state.RawOrientation.GetCameraRotationToTarget( state.ReferenceLookAt - state.CorrectedPosition, state.ReferenceUp); } Vector3 offset = m_Offset; if (m_ScreenProportion) { float dis = (state.ReferenceLookAt - transform.position).magnitude - offset.z; float disY = Mathf.Tan(25 * Mathf.Deg2Rad) * dis; float disX = disY * Screen.width / Screen.height; offset = new Vector3(disX * m_Offset.x, disY * m_Offset.y, m_Offset.z); } offset = state.RawOrientation * offset; state.PositionCorrection += offset; if (!preserveAim) { //state.ReferenceLookAt += offset; } else { var q = Quaternion.LookRotation( state.ReferenceLookAt - state.CorrectedPosition, state.ReferenceUp); q = q.ApplyCameraRotation(-screenOffset, state.ReferenceUp); state.RawOrientation = q; } m_AutoAdjust.AutoAdjustOffset(vcam, state, deltaTime, ref m_Offset); } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime ) { if (vcam.Follow == null) { return; } if (stage != CinemachineCore.Stage.Aim) { return; } if (inputs == null) { return; } if (startingRot == null) { startingRot = transform.localRotation.eulerAngles; } var deltaRot = inputs.Look * Time.deltaTime; startingRot.x += deltaRot.x; if (invertY) { startingRot.y += deltaRot.y; } else { startingRot.y -= deltaRot.y; } startingRot.y = Mathf.Clamp(startingRot.y, -clampViewY, clampViewY); state.RawOrientation = Quaternion.Euler(new Vector3(startingRot.y, startingRot.x, 0f)); }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Body) { //if (Input.GetKeyDown("a")) //{ // transform.eulerAngles += new Vector3(0f, -5f, 0f); //} //if (Input.GetKeyDown("d")) //{ // transform.eulerAngles += new Vector3(0f, +5f, 0f); //} //var pos = state.RawPosition; //pos.y = m_YPosition; //pos.x = m_XPosition; //state.RawPosition = pos; } }
/// <summary>Callback to tweak the orthographic size</summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="stage">The current pipeline stage</param> /// <param name="state">The current virtual camera state</param> /// <param name="deltaTime">The current applicable deltaTime</param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { // This must run during the Body stage because CinemachineConfiner also runs during Body stage, // and CinemachinePixelPerfect needs to run before CinemachineConfiner as the confiner reads the // orthographic size. We also altered the script execution order to ensure this. if (stage != CinemachineCore.Stage.Body) { return; } var brain = CinemachineCore.Instance.FindPotentialTargetBrain(vcam); if (brain == null || !brain.IsLive(vcam)) { return; } #if CINEMACHINE_LWRP_7_3_1 UnityEngine.Experimental.Rendering.Universal.PixelPerfectCamera pixelPerfectCamera; #elif CINEMACHINE_PIXEL_PERFECT_2_0_3 UnityEngine.U2D.PixelPerfectCamera pixelPerfectCamera; #endif brain.TryGetComponent(out pixelPerfectCamera); if (pixelPerfectCamera == null || !pixelPerfectCamera.isActiveAndEnabled) { return; } #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying && !pixelPerfectCamera.runInEditMode) { return; } #endif var lens = state.Lens; lens.OrthographicSize = pixelPerfectCamera.CorrectCinemachineOrthoSize(lens.OrthographicSize); state.Lens = lens; }
private void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, CameraState previousState, float deltaTime) { if (enabled) { if (stage == CinemachineCore.Stage.Body) { if (m_PositionSmoothing > 0) { if (deltaTime <= 0) { mSmoothingFilter = null; // reset the filter } state.PositionCorrection += ApplySmoothing(vcam, state.CorrectedPosition) - state.CorrectedPosition; } if (m_LookAtSmoothing > 0 && state.HasLookAt) { if (deltaTime <= 0) { mSmoothingFilterLookAt = null; // reset the filter } state.ReferenceLookAt = ApplySmoothingLookAt(vcam, state.ReferenceLookAt); } } if (stage == CinemachineCore.Stage.Aim) { if (m_RotationSmoothing > 0) { if (deltaTime <= 0) { mSmoothingFilterRotation = null; // reset the filter } Quaternion q = Quaternion.Inverse(state.CorrectedOrientation) * ApplySmoothing(vcam, state.CorrectedOrientation, state.ReferenceUp); state.OrientationCorrection = state.OrientationCorrection * q; } } } }
/// <summary> /// Updates FadeOut shader on the specified FadeOutMaterial. /// </summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="stage">The current pipeline stage</param> /// <param name="state">The current virtual camera state</param> /// <param name="deltaTime">The current applicable deltaTime</param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Finalize) { if (m_FadeOutMaterial == null || !m_FadeOutMaterial.HasProperty(k_MaxDistanceID) || !m_FadeOutMaterial.HasProperty(k_MinDistanceID)) { return; } if (m_SetToCameraToLookAtDistance && vcam.LookAt != null) { m_MaxDistance = Vector3.Distance(vcam.transform.position, vcam.LookAt.position) - m_LookAtTargetRadius; } m_FadeOutMaterial.SetFloat(k_MaxDistanceID, m_MaxDistance); m_FadeOutMaterial.SetFloat(k_MinDistanceID, m_MinDistance); } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Aim) { Vector3 shakePos = Vector3.zero; Quaternion shakeRot = Quaternion.identity; if (CinemachineScreenShakeManager.Instance.GetShake(out shakePos, out shakeRot)) { if (ScreenSpace) { shakeMatrix.SetTRS(Vector3.zero, state.FinalOrientation, Vector3.one); shakePos = shakeMatrix.MultiplyPoint(shakePos * m_Gain); } state.PositionCorrection += shakePos; shakeRot = Quaternion.SlerpUnclamped(Quaternion.identity, shakeRot, -m_Gain); state.OrientationCorrection *= shakeRot; } } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { //UnityEngine.Profiling.Profiler.BeginSample("CinemachinePostProcessing.PostPipelineStageCallback"); // Set the focus after the camera has been fully positioned. // GML todo: what about collider? if (stage == CinemachineCore.Stage.FreeRunAim) { if (!IsValid) { DestroyProfileCopy(); } else { // Handle Follow Focus if (!m_FocusTracksTarget || !state.HasLookAt) { DestroyProfileCopy(); } else { if (mProfileCopy == null || mCachedProfileIsInvalid) { CreateProfileCopy(); } DepthOfField dof; if (mProfileCopy.TryGetSettings(out dof)) { dof.focusDistance.value = (state.FinalPosition - state.ReferenceLookAt).magnitude + m_FocusOffset; } } // Apply the post-processing state.AddCustomBlendable(new CameraState.CustomBlendable(this, 1)); } } //UnityEngine.Profiling.Profiler.EndSample(); }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Body) { var pos = state.RawPosition; if (LockOnXAxis) { pos.x = XPosition; } if (LockOnYAxis) { pos.y = YPosition; } if (LockOnZAxis) { pos.z = ZPosition; } state.RawPosition = pos; } }
public T AddCinemachineComponent <T>() where T : CinemachineComponentBase { Transform componentOwner = this.GetComponentOwner(); CinemachineComponentBase[] components = componentOwner.GetComponents <CinemachineComponentBase>(); T t = componentOwner.gameObject.AddComponent <T>(); if (t != null && components != null) { CinemachineCore.Stage stage = t.Stage; for (int i = components.Length - 1; i >= 0; i--) { if (components[i].Stage == stage) { components[i].enabled = false; UnityEngine.Object.DestroyImmediate(components[i]); } } } this.InvalidateComponentPipeline(); return(t); }
/// <summary> /// Locks position /// </summary> /// <param name="vcam"></param> /// <param name="stage"></param> /// <param name="state"></param> /// <param name="deltaTime"></param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (enabled && stage == CinemachineCore.Stage.Body) { var pos = state.RawPosition; if (LockXAxis) { pos.x = _forcedPosition.x; } if (LockYAxis) { pos.y = _forcedPosition.y; } if (LockZAxis) { pos.z = _forcedPosition.z; } state.RawPosition = pos; } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == CinemachineCore.Stage.Body) { float minY = bounds.min.y + Camera.main.orthographicSize; float maxY = bounds.max.y - Camera.main.orthographicSize; var pos = state.RawPosition; if (pos.y < minY) { pos.y = minY; } if (pos.y > maxY) { pos.y = maxY; } state.RawPosition = pos; } }
protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime ) { if (stage != CinemachineCore.Stage.Aim) { return; } if (inputs == null) { return; } if (!inputs.IsLocked) { return; } EvaluateRotation(ref state); EvaluatePosition(ref state, deltaTime); }
private void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, CameraState previousState, float deltaTime) { if (enabled) { // Set the zoom after the body has been positioned, but before the aim, // so that composer can compose using the updated fov. if (stage == CinemachineCore.Stage.Body) { // Try to reproduce the target width float targetWidth = Mathf.Max(m_Width, 0); float fov = 179f; float d = Vector3.Distance(state.CorrectedPosition, state.ReferenceLookAt); if (d > UnityVectorExtensions.Epsilon) { // Apply damping if (deltaTime > 0 && m_Damping > 0) { // Clamp targetWidth to FOV min/max float minW = d * 2f * Mathf.Tan(m_MinFOV * Mathf.Deg2Rad / 2f); float maxW = d * 2f * Mathf.Tan(m_MaxFOV * Mathf.Deg2Rad / 2f); targetWidth = Mathf.Clamp(targetWidth, minW, maxW); float currentWidth = d * 2f * Mathf.Tan(previousState.Lens.FieldOfView * Mathf.Deg2Rad / 2f); float delta = targetWidth - currentWidth; delta *= deltaTime / Mathf.Max(m_Damping * kHumanReadableDampingScalar, deltaTime); targetWidth = currentWidth + delta; } fov = 2f * Mathf.Atan(targetWidth / (2 * d)) * Mathf.Rad2Deg; } LensSettings lens = state.Lens; lens.FieldOfView = Mathf.Clamp(fov, m_MinFOV, m_MaxFOV); state.Lens = lens; } } }
public void CreateSubeditors(UnityEditor.Editor parentEditor) { mParentEditor = parentEditor; m_subeditors = new VcamStageEditor[(int)CinemachineCore.Stage.Finalize]; CinemachineNewVirtualCamera owner = mParentEditor == null ? null : mParentEditor.target as CinemachineNewVirtualCamera; if (owner == null) { return; } for (CinemachineCore.Stage stage = CinemachineCore.Stage.Body; stage < CinemachineCore.Stage.Finalize; ++stage) { var ed = new VcamStageEditor(stage, owner.gameObject); m_subeditors[(int)stage] = ed; ed.SetComponent = (type) => { var vcam = mParentEditor.target as CinemachineNewVirtualCamera; if (vcam != null) { var c = Undo.AddComponent(vcam.gameObject, type); c.hideFlags |= HideFlags.HideInInspector; vcam.InvalidateComponentCache(); } }; ed.DestroyComponent = (component) => { var vcam = mParentEditor.target as CinemachineNewVirtualCamera; if (vcam != null) { Undo.DestroyObjectImmediate(component); vcam.InvalidateComponentCache(); } }; } }
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; } }
/// <summary>Callback to tweak the settings</summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="stage">The current pipeline stage</param> /// <param name="state">The current virtual camera state</param> /// <param name="deltaTime">The current applicable deltaTime</param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (stage == m_ApplyAfter) { var lens = state.Lens; // Tilt by local X var qTilted = state.RawOrientation * Quaternion.AngleAxis(m_Tilt, Vector3.right); // Pan in world space var qDesired = Quaternion.AngleAxis(m_Pan, state.ReferenceUp) * qTilted; state.OrientationCorrection = Quaternion.Inverse(state.CorrectedOrientation) * qDesired; // And dutch at the end lens.Dutch += m_Dutch; // Finally zoom if (m_ZoomScale != 1) { lens.OrthographicSize *= m_ZoomScale; lens.FieldOfView *= m_ZoomScale; } state.Lens = lens; } }
private void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, CameraState previousState, float deltaTime) { if (enabled) { // Set the zoom after the body has been positioned, but before the aim, // so that composer can compose using the updated fov. if (stage == CinemachineCore.Stage.Body) { // Try to reproduce the target width float width = Mathf.Max(m_Width, 0); float fov = 179f; float d = Vector3.Distance(state.CorrectedPosition, state.ReferenceLookAt); if (d > UnityVectorExtensions.Epsilon) { fov = 2f * Mathf.Atan(width / (2 * d)) * Mathf.Rad2Deg; } LensSettings lens = state.Lens; lens.FieldOfView = Mathf.Clamp(fov, 1, 179f); state.Lens = lens; } } }
/// <summary> /// Applies the specified offset to the camera state /// </summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="stage">The current pipeline stage</param> /// <param name="state">The current virtual camera state</param> /// <param name="deltaTime">The current applicable deltaTime</param> protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { if (!m_Active) { return; } if (stage == m_ApplyAfter) { bool preserveAim = m_PreserveComposition && state.HasLookAt && stage > CinemachineCore.Stage.Body; Vector3 screenOffset = Vector2.zero; if (preserveAim) { screenOffset = state.RawOrientation.GetCameraRotationToTarget( state.ReferenceLookAt - state.CorrectedPosition, state.ReferenceUp); } Vector3 offset = state.RawOrientation * m_Offset; state.PositionCorrection += offset; if (!preserveAim) { state.ReferenceLookAt += offset; } else { var q = Quaternion.LookRotation( state.ReferenceLookAt - state.CorrectedPosition, state.ReferenceUp); q = q.ApplyCameraRotation(-screenOffset, state.ReferenceUp); state.RawOrientation = q; } } }
//VirtualCamera用来在流水线中计算State的接口 protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam, CinemachineCore.Stage stage, ref CameraState state, float deltaTime) { //由于这个接口在么个阶段后都会调用,所以要加这个判断。 //保证只在Aim结束后指调用一次 if (stage == CinemachineCore.Stage.Aim) { Vector3 impulsePos = Vector3.zero; Quaternion impulseRot = Quaternion.identity; //直接调ImpulseManager的接口获取gameShakeChannel产生的震动数据, //位置填zero,保证噪音不会衰减 if (CinemachineImpulseManager.Instance.GetImpulseAt( Vector3.zero, m_Use2DDistance, m_ChannelMask, out impulsePos, out impulseRot)) { //转换到世界坐标 shakeMatrix.SetTRS(Vector3.zero, state.FinalOrientation, Vector3.one); //增加强度参数的影响后,应用到当前State上 state.PositionCorrection += shakeMatrix.MultiplyPoint(impulsePos * -m_Gain); impulseRot = Quaternion.SlerpUnclamped(Quaternion.identity, impulseRot, -m_Gain); state.OrientationCorrection = state.OrientationCorrection * impulseRot; } } }
void UpdateStageState(ICinemachineComponent[] components) { if (m_stageState == null) { m_stageState = new int[System.Enum.GetValues(typeof(CinemachineCore.Stage)).Length]; } for (int i = 0; i < m_stageState.Length; ++i) { m_stageState[i] = 0; } foreach (var c in components) { CinemachineCore.Stage stage = c.Stage; int index = 0; for (index = sStageData[(int)stage].types.Length - 1; index > 0; --index) { if (sStageData[(int)stage].types[index] == c.GetType()) { break; } } m_stageState[(int)stage] = index; } }