#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