using UnityEngine; // NOTE: If you are getting errors of the sort that say something like: // "The type or namespace name `PostProcessing' does not exist in the namespace" // it is because the PostProcessing v1 module has been removed from your project. // // To make the errors go away, you can either: // 1 - Download PostProcessing V1 and install it into your project // or // 2 - Go into PlayerSettings/OtherSettings and remove the Scripting Define for UNITY_POST_PROCESSING_STACK_V1 // namespace Cinemachine.PostFX { #if UNITY_POST_PROCESSING_STACK_V1 && !UNITY_POST_PROCESSING_STACK_V2 /// /// This behaviour is a liaison between Cinemachine with the Post-Processing v1 module. You must /// have the Post-Processing V1 stack asset store package installed in order to use this behaviour. /// /// It's used in 2 ways: /// /// * As a component on the Unity Camera: it serves as the liaison /// between the camera's CinemachineBrain and the camera's Post-Processing behaviour. /// It listens for camera Cut events and resets the Post-Processing stack when they occur. /// If you are using Post-Processing, then you should add this behaviour to your /// camera alongside the CinemachineBrain, always. /// /// * As a component on the Virtual Camera: In this capacity, it holds /// a Post-Processing Profile asset that will be applied to the Unity camera whenever /// the Virtual camera is live. It also has the (temporary) optional functionality of animating /// the Focus Distance and DepthOfField properties of the Camera State, and /// applying them to the current Post-Processing profile. /// [DocumentationSorting(100, DocumentationSortingAttribute.Level.UserRef)] [ExecuteInEditMode] [DisallowMultipleComponent] [AddComponentMenu("Cinemachine/CinemachinePostFX")] [SaveDuringPlay] public class CinemachinePostFX : MonoBehaviour { // Just for the Enabled checkbox void Update() {} [Tooltip("When this behaviour is on a Unity Camera, this setting is the default Post-Processing profile for the camera, and will be applied whenever it is not overridden by a virtual camera. When the behaviour is on a virtual camera, then this is the Post-Processing profile that will become active whenever this virtual camera is live")] public UnityEngine.PostProcessing.PostProcessingProfile m_Profile; [Tooltip("If checked, then the Focus Distance will be set to the distance between the camera and the LookAt target.")] public bool m_FocusTracksTarget; [Tooltip("Offset from target distance, to be used with Focus Tracks Target.")] public float m_FocusOffset; // These are used if this behaviour is on a Unity Camera CinemachineBrain mBrain; UnityEngine.PostProcessing.PostProcessingBehaviour mPostProcessingBehaviour; void ConnectToBrain() { // If I am a component on the Unity camera, connect to its brain // and to its post-processing behaviour mBrain = GetComponent(); if (mBrain != null) { mBrain.m_CameraCutEvent.RemoveListener(OnCameraCut); mBrain.m_CameraCutEvent.AddListener(OnCameraCut); } // Must have one of these if connected to a brain mPostProcessingBehaviour = GetComponent(); if (mPostProcessingBehaviour == null && mBrain != null) mPostProcessingBehaviour = gameObject.AddComponent(); } void OnDestroy() { if (mBrain != null) mBrain.m_CameraCutEvent.RemoveListener(OnCameraCut); } // CinemachineBrain callback used when this behaviour is on the Unity Camera internal void PostFXHandler(CinemachineBrain brain) { //UnityEngine.Profiling.Profiler.BeginSample("CinemachinePostFX.PostFXHandler"); ICinemachineCamera vcam = brain.ActiveVirtualCamera; if (enabled && mBrain != null && mPostProcessingBehaviour != null) { // Look for the vcam's PostFX behaviour CinemachinePostFX postFX = GetEffectivePostFX(vcam); if (postFX == null) postFX = this; // vcam does not define a profile - apply the default if (postFX.m_Profile != null) { // Adjust the focus distance CameraState state = brain.CurrentCameraState; UnityEngine.PostProcessing.DepthOfFieldModel.Settings dof = postFX.m_Profile.depthOfField.settings; if (postFX.m_FocusTracksTarget && state.HasLookAt) dof.focusDistance = (state.FinalPosition - state.ReferenceLookAt).magnitude + postFX.m_FocusOffset; postFX.m_Profile.depthOfField.settings = dof; } // Apply the profile if (mPostProcessingBehaviour.profile != postFX.m_Profile) { mPostProcessingBehaviour.profile = postFX.m_Profile; mPostProcessingBehaviour.ResetTemporalEffects(); } } //UnityEngine.Profiling.Profiler.EndSample(); } CinemachinePostFX GetEffectivePostFX(ICinemachineCamera vcam) { while (vcam != null && vcam.LiveChildOrSelf != vcam) vcam = vcam.LiveChildOrSelf; CinemachinePostFX postFX = null; while (vcam != null && postFX == null) { CinemachineVirtualCameraBase vcamBase = vcam as CinemachineVirtualCameraBase; if (vcamBase != null) postFX = vcamBase.GetComponent(); if (postFX != null && !postFX.enabled) postFX = null; vcam = vcam.ParentCamera; } return postFX; } void OnCameraCut(CinemachineBrain brain) { if (mPostProcessingBehaviour != null) { //Debug.Log("CinemachinePostFX.OnCameraCut()"); mPostProcessingBehaviour.ResetTemporalEffects(); } } static void StaticPostFXHandler(CinemachineBrain brain) { CinemachinePostFX postFX = brain.PostProcessingComponent as CinemachinePostFX; if (postFX == null) { brain.PostProcessingComponent = brain.GetComponent(); postFX = brain.PostProcessingComponent as CinemachinePostFX; if (postFX != null) postFX.ConnectToBrain(); } if (postFX != null) postFX.PostFXHandler(brain); } /// Internal method called by editor module [RuntimeInitializeOnLoadMethod] public static void InitializeModule() { // When the brain pushes the state to the camera, hook in to the PostFX CinemachineBrain.sPostProcessingHandler.RemoveListener(StaticPostFXHandler); CinemachineBrain.sPostProcessingHandler.AddListener(StaticPostFXHandler); } } #endif }