using UnityEngine; namespace Cinemachine { /// /// An abstract representation of a mutator acting on a Cinemachine Virtual Camera /// [DocumentationSorting(DocumentationSortingAttribute.Level.API)] public abstract class CinemachineComponentBase : MonoBehaviour { /// Useful constant for very small floats protected const float Epsilon = Utility.UnityVectorExtensions.Epsilon; /// Get the associated CinemachineVirtualCameraBase public CinemachineVirtualCameraBase VirtualCamera { get { if (m_vcamOwner == null) m_vcamOwner = GetComponent(); if (m_vcamOwner == null && transform.parent != null) m_vcamOwner = transform.parent.GetComponent(); return m_vcamOwner; } } CinemachineVirtualCameraBase m_vcamOwner; /// Returns the owner vcam's Follow target. public Transform FollowTarget { get { CinemachineVirtualCameraBase vcam = VirtualCamera; return vcam == null ? null : vcam.ResolveFollow(vcam.Follow); } } /// Returns the owner vcam's LookAt target. public Transform LookAtTarget { get { CinemachineVirtualCameraBase vcam = VirtualCamera; return vcam == null ? null : vcam.ResolveLookAt(vcam.LookAt); } } /// Get Follow target as ICinemachineTargetGroup, or null if target is not a group public ICinemachineTargetGroup AbstractFollowTargetGroup { get { CinemachineVirtualCameraBase vcam = VirtualCamera; return vcam == null ? null : vcam.AbstractFollowTargetGroup; } } /// Get Follow target as CinemachineTargetGroup, or null if target is not a CinemachineTargetGroup public CinemachineTargetGroup FollowTargetGroup => AbstractFollowTargetGroup as CinemachineTargetGroup; /// Get the position of the Follow target. Special handling: If the Follow target is /// a VirtualCamera, returns the vcam State's position, not the transform's position public Vector3 FollowTargetPosition { get { var vcam = VirtualCamera.FollowTargetAsVcam; if (vcam != null) return vcam.State.FinalPosition; Transform target = FollowTarget; if (target != null) return TargetPositionCache.GetTargetPosition(target); return Vector3.zero; } } /// Get the rotation of the Follow target. Special handling: If the Follow target is /// a VirtualCamera, returns the vcam State's rotation, not the transform's rotation public Quaternion FollowTargetRotation { get { var vcam = VirtualCamera.FollowTargetAsVcam; if (vcam != null) return vcam.State.FinalOrientation; Transform target = FollowTarget; if (target != null) return TargetPositionCache.GetTargetRotation(target); return Quaternion.identity; } } /// Get LookAt target as ICinemachineTargetGroup, or null if target is not a group public ICinemachineTargetGroup AbstractLookAtTargetGroup => VirtualCamera.AbstractLookAtTargetGroup; /// Get LookAt target as CinemachineTargetGroup, or null if target is not a CinemachineTargetGroup public CinemachineTargetGroup LookAtTargetGroup => AbstractLookAtTargetGroup as CinemachineTargetGroup; /// Get the position of the LookAt target. Special handling: If the LookAt target is /// a VirtualCamera, returns the vcam State's position, not the transform's position public Vector3 LookAtTargetPosition { get { var vcam = VirtualCamera.LookAtTargetAsVcam; if (vcam != null) return vcam.State.FinalPosition; Transform target = LookAtTarget; if (target != null) return TargetPositionCache.GetTargetPosition(target); return Vector3.zero; } } /// Get the rotation of the LookAt target. Special handling: If the LookAt target is /// a VirtualCamera, returns the vcam State's rotation, not the transform's rotation public Quaternion LookAtTargetRotation { get { var vcam = VirtualCamera.LookAtTargetAsVcam; if (vcam != null) return vcam.State.FinalOrientation; Transform target = LookAtTarget; if (target != null) return TargetPositionCache.GetTargetRotation(target); return Quaternion.identity; } } /// Returns the owner vcam's CameraState. public CameraState VcamState { get { CinemachineVirtualCameraBase vcam = VirtualCamera; return vcam == null ? CameraState.Default : vcam.State; } } /// Returns true if this object is enabled and set up to produce results. public abstract bool IsValid { get; } /// Override this to do such things as offset the RefereceLookAt. /// Base class implementation does nothing. /// Input state that must be mutated /// Current effective deltaTime public virtual void PrePipelineMutateCameraState(ref CameraState curState, float deltaTime) {} /// What part of the pipeline this fits into public abstract CinemachineCore.Stage Stage { get; } /// Special for Body Stage compoments that want to be applied after Aim /// stage because they use the aim as inout for the procedural placement public virtual bool BodyAppliesAfterAim { get { return false; } } /// Mutates the camera state. This state will later be applied to the camera. /// Input state that must be mutated /// Delta time for time-based effects (ignore if less than 0) public abstract void MutateCameraState(ref CameraState curState, float deltaTime); /// Notification that this virtual camera is going live. /// Base class implementation does nothing. /// The camera being deactivated. May be null. /// Default world Up, set by the CinemachineBrain /// Delta time for time-based effects (ignore if less than or equal to 0) /// Transition settings for this vcam /// True if the vcam should do an internal update as a result of this call public virtual bool OnTransitionFromCamera( ICinemachineCamera fromCam, Vector3 worldUp, float deltaTime, ref CinemachineVirtualCameraBase.TransitionParams transitionParams) { return false; } /// This is called to notify the component that a target got warped, /// so that the component can update its internal state to make the camera /// also warp seamlessy. Base class implementation does nothing. /// The object that was warped /// The amount the target's position changed public virtual void OnTargetObjectWarped(Transform target, Vector3 positionDelta) {} /// /// Force the virtual camera to assume a given position and orientation. /// Procedural placement then takes over. /// Base class implementation does nothing. /// Worldspace pposition to take /// Worldspace orientation to take public virtual void ForceCameraPosition(Vector3 pos, Quaternion rot) {} /// /// Report maximum damping time needed for this component. /// Only used in editor for timeline scrubbing. /// /// Highest damping setting in this component public virtual float GetMaxDampTime() { return 0; } /// Components that require user input should implement this and return true. public virtual bool RequiresUserInput => false; } }