#if !CINEMACHINE_NO_CM2_SUPPORT using UnityEngine; using System; using Unity.Cinemachine.TargetTracking; namespace Unity.Cinemachine { /// /// This is a deprecated component. Use CinemachineOrbitalFollow instead. /// [Obsolete("CinemachineTransposer has been deprecated. Use CinemachineFollow instead")] [AddComponentMenu("")] // Don't display in add component menu [SaveDuringPlay] [CameraPipeline(CinemachineCore.Stage.Body)] public class CinemachineTransposer : CinemachineComponentBase { /// The coordinate space to use when interpreting the offset from the target [Tooltip("The coordinate space to use when interpreting the offset from the target. This is also " + "used to set the camera's Up vector, which will be maintained when aiming the camera.")] public BindingMode m_BindingMode = BindingMode.LockToTargetWithWorldUp; /// The distance which the transposer will attempt to maintain from the transposer subject [Tooltip("The distance vector that the transposer will attempt to maintain from the Follow target")] public Vector3 m_FollowOffset = Vector3.back * 10f; /// How aggressively the camera tries to maintain the offset in the X-axis. /// Small numbers are more responsive, rapidly translating the camera to keep the target's /// x-axis offset. Larger numbers give a more heavy slowly responding camera. /// Using different settings per axis can yield a wide range of camera behaviors [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to maintain the offset in the X-axis. Small numbers " + "are more responsive, rapidly translating the camera to keep the target's x-axis offset. " + "Larger numbers give a more heavy slowly responding camera. Using different settings per " + "axis can yield a wide range of camera behaviors.")] public float m_XDamping = 1f; /// How aggressively the camera tries to maintain the offset in the Y-axis. /// Small numbers are more responsive, rapidly translating the camera to keep the target's /// y-axis offset. Larger numbers give a more heavy slowly responding camera. /// Using different settings per axis can yield a wide range of camera behaviors [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to maintain the offset in the Y-axis. Small numbers " + "are more responsive, rapidly translating the camera to keep the target's y-axis offset. " + "Larger numbers give a more heavy slowly responding camera. Using different settings per " + "axis can yield a wide range of camera behaviors.")] public float m_YDamping = 1f; /// How aggressively the camera tries to maintain the offset in the Z-axis. /// Small numbers are more responsive, rapidly translating the camera to keep the /// target's z-axis offset. Larger numbers give a more heavy slowly responding camera. /// Using different settings per axis can yield a wide range of camera behaviors [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to maintain the offset in the Z-axis. " + "Small numbers are more responsive, rapidly translating the camera to keep the " + "target's z-axis offset. Larger numbers give a more heavy slowly responding camera. " + "Using different settings per axis can yield a wide range of camera behaviors.")] public float m_ZDamping = 1f; /// How to calculate the angular damping for the target orientation. /// Use Quaternion if you expect the target to take on very steep pitches, which would /// be subject to gimbal lock if Eulers are used. public AngularDampingMode m_AngularDampingMode = AngularDampingMode.Euler; /// How aggressively the camera tries to track the target rotation's X angle. /// Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera. [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to track the target rotation's X angle. " + "Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera.")] public float m_PitchDamping = 0; /// How aggressively the camera tries to track the target rotation's Y angle. /// Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera. [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to track the target rotation's Y angle. " + "Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera.")] public float m_YawDamping = 0; /// How aggressively the camera tries to track the target rotation's Z angle. /// Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera. [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to track the target rotation's Z angle. " + "Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera.")] public float m_RollDamping = 0f; /// How aggressively the camera tries to track the target's orientation. /// Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera. [Range(0f, 20f)] [Tooltip("How aggressively the camera tries to track the target's orientation. " + "Small numbers are more responsive. Larger numbers give a more heavy slowly responding camera.")] public float m_AngularDamping = 0f; /// /// Helper object that tracks the Follow target, with damping /// Tracker m_TargetTracker; /// Get the damping settings protected TrackerSettings TrackerSettings => new TrackerSettings { BindingMode = m_BindingMode, PositionDamping = new Vector3(m_XDamping, m_YDamping, m_ZDamping), RotationDamping = new Vector3(m_PitchDamping, m_YawDamping, m_RollDamping), AngularDampingMode = m_AngularDampingMode, QuaternionDamping = m_AngularDamping }; /// Derived classes should call this from their OnValidate() implementation protected virtual void OnValidate() { m_FollowOffset = EffectiveOffset; } /// Hide the offset in int inspector. Used by FreeLook. internal bool HideOffsetInInspector { get; set; } /// Get the target offset, with sanitization public Vector3 EffectiveOffset { get { Vector3 offset = m_FollowOffset; if (m_BindingMode == BindingMode.LazyFollow) { offset.x = 0; offset.z = -Mathf.Abs(offset.z); } return offset; } } /// True if component is enabled and has a valid Follow target public override bool IsValid { get { return enabled && FollowTarget != null; } } /// Get the Cinemachine Pipeline stage that this component implements. /// Always returns the Body stage public override CinemachineCore.Stage Stage { get { return CinemachineCore.Stage.Body; } } /// /// Report maximum damping time needed for this component. /// /// Highest damping setting in this component public override float GetMaxDampTime() => TrackerSettings.GetMaxDampTime(); /// Positions the virtual camera according to the transposer rules. /// The current camera state /// Used for damping. If less than 0, no damping is done. public override void MutateCameraState(ref CameraState curState, float deltaTime) { m_TargetTracker.InitStateInfo(this, deltaTime, m_BindingMode, curState.ReferenceUp); if (IsValid) { Vector3 offset = EffectiveOffset; m_TargetTracker.TrackTarget( this, deltaTime, curState.ReferenceUp, offset, TrackerSettings, out Vector3 pos, out Quaternion orient); offset = orient * offset; curState.ReferenceUp = orient * Vector3.up; // Respect minimum target distance on XZ plane var targetPosition = FollowTargetPosition; pos += m_TargetTracker.GetOffsetForMinimumTargetDistance( this, pos, offset, curState.RawOrientation * Vector3.forward, curState.ReferenceUp, targetPosition); curState.RawPosition = pos + offset; } } /// This is called to notify the user that a target got warped, /// so that we can update its internal state to make the camera /// also warp seamlessly. /// The object that was warped /// The amount the target's position changed public override void OnTargetObjectWarped(Transform target, Vector3 positionDelta) { base.OnTargetObjectWarped(target, positionDelta); if (target == FollowTarget) m_TargetTracker.OnTargetObjectWarped(positionDelta); } /// /// Force the virtual camera to assume a given position and orientation /// /// Worldspace position to take /// Worldspace orientation to take public override void ForceCameraPosition(Vector3 pos, Quaternion rot) { base.ForceCameraPosition(pos, rot); m_TargetTracker.ForceCameraPosition(this, m_BindingMode, pos, rot, EffectiveOffset); } internal Quaternion GetReferenceOrientation(Vector3 up) { return m_TargetTracker.GetReferenceOrientation(this, m_BindingMode, up); } /// Internal API for the Inspector Editor, so it can draw a marker at the target /// Current effective world up /// The position of the Follow target internal virtual Vector3 GetTargetCameraPosition(Vector3 worldUp) { if (!IsValid) return Vector3.zero; return FollowTargetPosition + m_TargetTracker.GetReferenceOrientation( this, m_BindingMode, worldUp) * EffectiveOffset; } // Helper to upgrade to CM3 internal void UpgradeToCm3(CinemachineFollow c) { c.FollowOffset = m_FollowOffset; c.TrackerSettings = TrackerSettings; } } } #endif