using UnityEngine; using Cinemachine; /// <summary> /// An add-on module for Cinemachine Virtual Camera that adds a final tweak to the camera /// comnposition. It is intended for use in a Timeline context, where you want to hand-adjust /// the output of procedural or recorded camera aiming. /// </summary> [AddComponentMenu("")] // Hide in menu [ExecuteAlways] [SaveDuringPlay] [HelpURL(Documentation.BaseURL + "manual/CinemachineRecomposer.html")] public class CinemachineRecomposer : CinemachineExtension { /// <summary> /// When to apply the adjustment /// </summary> [Tooltip("When to apply the adjustment")] public CinemachineCore.Stage m_ApplyAfter; /// <summary> /// Tilt the camera by this much /// </summary> [Tooltip("Tilt the camera by this much")] public float m_Tilt; /// <summary> /// Pan the camera by this much /// </summary> [Tooltip("Pan the camera by this much")] public float m_Pan; /// <summary> /// Roll the camera by this much /// </summary> [Tooltip("Roll the camera by this much")] public float m_Dutch; /// <summary> /// Scale the zoom by this amount (normal = 1) /// </summary> [Tooltip("Scale the zoom by this amount (normal = 1)")] public float m_ZoomScale; /// <summary> /// Lowering this value relaxes the camera's attention to the Follow target (normal = 1) /// </summary> [Range(0, 1)] [Tooltip("Lowering this value relaxes the camera's attention to the Follow target (normal = 1)")] public float m_FollowAttachment; /// <summary> /// Lowering this value relaxes the camera's attention to the LookAt target (normal = 1) /// </summary> [Range(0, 1)] [Tooltip("Lowering this value relaxes the camera's attention to the LookAt target (normal = 1)")] public float m_LookAtAttachment; private void Reset() { m_ApplyAfter = CinemachineCore.Stage.Finalize; m_Tilt = 0; m_Pan = 0; m_Dutch = 0; m_ZoomScale = 1; m_FollowAttachment = 1; m_LookAtAttachment = 1; } private void OnValidate() { m_ZoomScale = Mathf.Max(0.01f, m_ZoomScale); m_FollowAttachment = Mathf.Clamp01(m_FollowAttachment); m_LookAtAttachment = Mathf.Clamp01(m_LookAtAttachment); } /// <summary>Callback to set the target attachment</summary> /// <param name="vcam">The virtual camera being processed</param> /// <param name="curState">Input state that must be mutated</param> /// <param name="deltaTime">The current applicable deltaTime</param> public override void PrePipelineMutateCameraStateCallback( CinemachineVirtualCameraBase vcam, ref CameraState curState, float deltaTime) { vcam.FollowTargetAttachment = m_FollowAttachment; vcam.LookAtTargetAttachment = m_LookAtAttachment; } /// <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; } } }