/* Author: Reza Date: 7/2/25 Description: Has all the post processing camera effects that replicate real symptoms like dizziness, fainting, panic, etc */ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class PostProcessingManager : MonoBehaviour { public static PostProcessingManager Instance; // Defines the Global Volume public Volume volume; // All the effect overrides private Vignette vignette; private ChromaticAberration chromaticAberration; private MotionBlur motionBlur; private LensDistortion lensDistortion; private ColorAdjustments colorAdjustments; [Header("Effect Intensities")] // Editable override values in inspector [SerializeField] public AnimationCurve vignetteIntensity; [SerializeField] public AnimationCurve chromaticAberrationIntensity; [SerializeField] public AnimationCurve motionBlurIntensity; [SerializeField] public AnimationCurve lensDistortionIntensity; [SerializeField] public AnimationCurve colorAdjustmentsIntensity; // Checks if effect is active or not private bool isEffectActive = false; void Awake() { if (Instance == null) { Instance = this; } else { Destroy(gameObject); } } // Start is called before the first frame update void Start() { // Get references for effects volume.profile.TryGet(out vignette); volume.profile.TryGet(out chromaticAberration); volume.profile.TryGet(out motionBlur); volume.profile.TryGet(out lensDistortion); volume.profile.TryGet(out colorAdjustments); } // Update is called once per frame void Update() { } // Function to start effects if there is none currently, and stop current effects to start next ones public void TriggerEffect(string effectName) { // If an effect is already active if (isEffectActive) { // Stop the effect StopEffect(effectName); } // If there's no active effects else { // Start the effect StartEffect(effectName); } } // Function to start the effect public void StartEffect(string effectName) { // The effect is active isEffectActive = true; // Calls coroutine to apply the effect StartCoroutine(ApplyEffect(effectName)); } // Function to stop the effect public void StopEffect(string effectName) { // The effect is not active isEffectActive = false; // Reset effects to default if (vignette != null) vignette.intensity.Override(0f); if (chromaticAberration != null) chromaticAberration.intensity.Override(0f); if (motionBlur != null) motionBlur.intensity.Override(0f); if (lensDistortion != null) lensDistortion.intensity.Override(0f); if (colorAdjustments != null) colorAdjustments.postExposure.Override(0f); } // Applies effects over time based on the type private IEnumerator ApplyEffect(string effectName) { float time = 0f; float duration = 1f; while (time < duration) { time += Time.deltaTime; float t = Mathf.Clamp01(time / duration); // Values for headache effect if (effectName == "Headache") { vignette.intensity.Override(vignetteIntensity.Evaluate(time)); chromaticAberration.intensity.Override(chromaticAberrationIntensity.Evaluate(time)); } // Values for dizziness effect else if (effectName == "Dizziness") { motionBlur.intensity.Override(motionBlurIntensity.Evaluate(time)); lensDistortion.intensity.Override(lensDistortionIntensity.Evaluate(time)); } yield return null; } } public void ApplyPanicEffect() { StartCoroutine(LoopPanicEffect()); } private IEnumerator LoopPanicEffect() { float time = 0f; float duration = 0.1f; while (isEffectActive) { time += Time.deltaTime; float t = Mathf.PingPong(time / duration, 1f); // Looping the effect // Apply intensity for panic effect vignette.intensity.Override(vignetteIntensity.Evaluate(t)); chromaticAberration.intensity.Override(chromaticAberrationIntensity.Evaluate(t)); motionBlur.intensity.Override(motionBlurIntensity.Evaluate(t)); lensDistortion.intensity.Override(lensDistortionIntensity.Evaluate(t)); colorAdjustments.postExposure.Override(colorAdjustmentsIntensity.Evaluate(t)); yield return null; } } }