| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- using System.Collections.Generic;
- using UnityEngine;
- namespace Cinemachine
- {
- /// <summary>
- /// Base class for a Cinemachine Virtual Camera extension module.
- /// Hooks into the Cinemachine Pipeline. Use this to add extra processing
- /// to the vcam, modifying its generated state
- /// </summary>
- [DocumentationSorting(DocumentationSortingAttribute.Level.API)]
- public abstract class CinemachineExtension : MonoBehaviour
- {
- /// <summary>Useful constant for very small floats</summary>
- protected const float Epsilon = Utility.UnityVectorExtensions.Epsilon;
- /// <summary>Get the CinemachineVirtualCamera to which this extension is attached</summary>
- public CinemachineVirtualCameraBase VirtualCamera
- {
- get
- {
- if (m_vcamOwner == null)
- m_vcamOwner = GetComponent<CinemachineVirtualCameraBase>();
- return m_vcamOwner;
- }
- }
- CinemachineVirtualCameraBase m_vcamOwner;
- /// <summary>Connect to virtual camera pipeline.
- /// Override implementations must call this base implementation</summary>
- protected virtual void Awake()
- {
- ConnectToVcam(true);
- }
- /// <summary>Does nothing. It's here for the little checkbox in the inspector.</summary>
- protected virtual void OnEnable() {}
- #if UNITY_EDITOR
- [UnityEditor.Callbacks.DidReloadScripts]
- static void OnScriptReload()
- {
- var extensions = Resources.FindObjectsOfTypeAll(
- typeof(CinemachineExtension)) as CinemachineExtension[];
- foreach (var e in extensions)
- e.ConnectToVcam(true);
- }
- #endif
- /// <summary>Disconnect from virtual camera pipeline.
- /// Override implementations must call this base implementation</summary>
- protected virtual void OnDestroy()
- {
- ConnectToVcam(false);
- }
- internal void EnsureStarted() { ConnectToVcam(true); }
- /// <summary>Connect to virtual camera. Implementation must be safe to be called
- /// redundantly. Override implementations must call this base implementation</summary>
- /// <param name="connect">True if connecting, false if disconnecting</param>
- protected virtual void ConnectToVcam(bool connect)
- {
- if (connect && VirtualCamera == null)
- Debug.LogError("CinemachineExtension requires a Cinemachine Virtual Camera component");
- if (VirtualCamera != null)
- {
- if (connect)
- VirtualCamera.AddExtension(this);
- else
- VirtualCamera.RemoveExtension(this);
- }
- mExtraState = null;
- }
- /// <summary>Override this to do such things as offset the RefereceLookAt.
- /// Base class implementation does nothing.</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 virtual void PrePipelineMutateCameraStateCallback(
- CinemachineVirtualCameraBase vcam, ref CameraState curState, float deltaTime) {}
- /// <summary>Legacy support. This is only here to avoid changing the API
- /// to make PostPipelineStageCallback() public</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>
- public void InvokePostPipelineStageCallback(
- CinemachineVirtualCameraBase vcam,
- CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
- {
- PostPipelineStageCallback(vcam, stage, ref state, deltaTime);
- }
- /// <summary>
- /// This callback will be called after the virtual camera has implemented
- /// each stage in the pipeline. This method may modify the referenced state.
- /// If deltaTime less than 0, reset all state info and perform no damping.
- /// </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 abstract void PostPipelineStageCallback(
- CinemachineVirtualCameraBase vcam,
- CinemachineCore.Stage stage, ref CameraState state, float deltaTime);
- /// <summary>This is called to notify the extension that a target got warped,
- /// so that the extension can update its internal state to make the camera
- /// also warp seamlessy. Base class implementation does nothing.</summary>
- /// <param name="target">The object that was warped</param>
- /// <param name="positionDelta">The amount the target's position changed</param>
- public virtual void OnTargetObjectWarped(Transform target, Vector3 positionDelta) {}
- /// <summary>
- /// Force the virtual camera to assume a given position and orientation
- /// </summary>
- /// <param name="pos">Worldspace pposition to take</param>
- /// <param name="rot">Worldspace orientation to take</param>
- public virtual void ForceCameraPosition(Vector3 pos, Quaternion rot) {}
-
- /// <summary>Notification that this virtual camera is going live.
- /// Base class implementation must be called by any overridden method.</summary>
- /// <param name="fromCam">The camera being deactivated. May be null.</param>
- /// <param name="worldUp">Default world Up, set by the CinemachineBrain</param>
- /// <param name="deltaTime">Delta time for time-based effects (ignore if less than or equal to 0)</param>
- /// <returns>True to request a vcam update of internal state</returns>
- public virtual bool OnTransitionFromCamera(
- ICinemachineCamera fromCam, Vector3 worldUp, float deltaTime) { return false; }
- /// <summary>
- /// Report maximum damping time needed for this extension.
- /// Only used in editor for timeline scrubbing.
- /// </summary>
- /// <returns>Highest damping setting in this extension</returns>
- public virtual float GetMaxDampTime() { return 0; }
- /// <summary>Because extensions can be placed on manager cams and will in that
- /// case be called for all the vcam children, vcam-specific state information
- /// should be stored here. Just define a class to hold your state info
- /// and use it exclusively when calling this.</summary>
- /// /// <typeparam name="T">The type of the extra state class</typeparam>
- /// <param name="vcam">The virtual camera being processed</param>
- /// <returns>The extra state, cast as type T</returns>
- protected T GetExtraState<T>(ICinemachineCamera vcam) where T : class, new()
- {
- if (mExtraState == null)
- mExtraState = new Dictionary<ICinemachineCamera, System.Object>();
- System.Object extra = null;
- if (!mExtraState.TryGetValue(vcam, out extra))
- extra = mExtraState[vcam] = new T();
- return extra as T;
- }
- /// <summary>Inefficient method to get all extra state info for all vcams.
- /// Intended for Editor use only, not runtime!
- /// </summary>
- /// <typeparam name="T">The extra state type</typeparam>
- /// <returns>A dynamically-allocated list with all the extra states</returns>
- protected List<T> GetAllExtraStates<T>() where T : class, new()
- {
- var list = new List<T>();
- if (mExtraState != null)
- foreach (var v in mExtraState)
- list.Add(v.Value as T);
- return list;
- }
- private Dictionary<ICinemachineCamera, System.Object> mExtraState;
- }
- }
|