using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; #if MM_URP using UnityEngine.Rendering.Universal; #endif using MoreMountains.Feedbacks; using MoreMountains.Tools; namespace MoreMountains.FeedbacksForThirdParty { /// /// Add this class to a Camera with a URP color adjustments post processing and it'll be able to "shake" its values by getting events /// #if MM_URP [RequireComponent(typeof(Volume))] #endif [AddComponentMenu("More Mountains/Feedbacks/Shakers/PostProcessing/MMChannelMixerShaker_URP")] public class MMChannelMixerShaker_URP : MMShaker { /// whether or not to add to the initial value public bool RelativeValues = true; [MMInspectorGroup("Red", true, 43)] /// the curve used to animate the red value on [Tooltip("the curve used to animate the red value on")] public AnimationCurve ShakeRed = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0)); /// the value to remap the curve's 0 to [Tooltip("the value to remap the curve's 0 to")] [Range(-200f, 200f)] public float RemapRedZero = 0f; /// the value to remap the curve's 1 to [Tooltip("the value to remap the curve's 1 to")] [Range(-200f, 200f)] public float RemapRedOne = 200f; [MMInspectorGroup("Green", true, 44)] /// the curve used to animate the green value on [Tooltip("the curve used to animate the green value on")] public AnimationCurve ShakeGreen = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0)); /// the value to remap the curve's 0 to [Tooltip("the value to remap the curve's 0 to")] [Range(-200f, 200f)] public float RemapGreenZero = 0f; /// the value to remap the curve's 1 to [Tooltip("the value to remap the curve's 1 to")] [Range(-200f, 200f)] public float RemapGreenOne = 200f; [MMInspectorGroup("Blue", true, 45)] /// the curve used to animate the blue value on [Tooltip("the curve used to animate the blue value on")] public AnimationCurve ShakeBlue = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0)); /// the value to remap the curve's 0 to [Tooltip("the value to remap the curve's 0 to")] [Range(-200f, 200f)] public float RemapBlueZero = 0f; /// the value to remap the curve's 1 to [Tooltip("the value to remap the curve's 1 to")] [Range(-200f, 200f)] public float RemapBlueOne = 200f; #if MM_URP protected Volume _volume; protected ChannelMixer _channelMixer; protected float _initialRed; protected float _initialGreen; protected float _initialBlue; protected float _initialContrast; protected Color _initialColorFilterColor; protected float _originalShakeDuration; protected bool _originalRelativeValues; protected AnimationCurve _originalShakeRed; protected float _originalRemapRedZero; protected float _originalRemapRedOne; protected AnimationCurve _originalShakeGreen; protected float _originalRemapGreenZero; protected float _originalRemapGreenOne; protected AnimationCurve _originalShakeBlue; protected float _originalRemapBlueZero; protected float _originalRemapBlueOne; /// /// On init we initialize our values /// protected override void Initialization() { base.Initialization(); _volume = this.gameObject.GetComponent(); _volume.profile.TryGet(out _channelMixer); } /// /// When that shaker gets added, we initialize its shake duration /// protected virtual void Reset() { ShakeDuration = 0.8f; } /// /// Shakes values over time /// protected override void Shake() { float newRed = ShakeFloat(ShakeRed, RemapRedZero, RemapRedOne, RelativeValues, _initialRed); _channelMixer.redOutRedIn.Override(newRed); float newGreen = ShakeFloat(ShakeGreen, RemapGreenZero, RemapGreenOne, RelativeValues, _initialGreen); _channelMixer.greenOutGreenIn.Override(newGreen); float newBlue = ShakeFloat(ShakeBlue, RemapBlueZero, RemapBlueOne, RelativeValues, _initialBlue); _channelMixer.blueOutBlueIn.Override(newBlue); } /// /// Collects initial values on the target /// protected override void GrabInitialValues() { _initialRed = _channelMixer.redOutRedIn.value; _initialGreen = _channelMixer.greenOutGreenIn.value; _initialBlue = _channelMixer.blueOutBlueIn.value; } /// /// When we get the appropriate event, we trigger a shake /// /// /// /// /// /// /// public virtual void OnMMChannelMixerShakeEvent(AnimationCurve shakeRed, float remapRedZero, float remapRedOne, AnimationCurve shakeGreen, float remapGreenZero, float remapGreenOne, AnimationCurve shakeBlue, float remapBlueZero, float remapBlueOne, float duration, bool relativeValues = false, float attenuation = 1.0f, MMChannelData channelData = null, bool resetShakerValuesAfterShake = true, bool resetTargetValuesAfterShake = true, bool forwardDirection = true, TimescaleModes timescaleMode = TimescaleModes.Scaled, bool stop = false, bool restore = false) { if (!CheckEventAllowed(channelData) || (!Interruptible && Shaking)) { return; } if (stop) { Stop(); return; } if (restore) { ResetTargetValues(); return; } _resetShakerValuesAfterShake = resetShakerValuesAfterShake; _resetTargetValuesAfterShake = resetTargetValuesAfterShake; if (resetShakerValuesAfterShake) { _originalShakeDuration = ShakeDuration; _originalRelativeValues = RelativeValues; _originalShakeRed = ShakeRed; _originalRemapRedZero = RemapRedZero; _originalRemapRedOne = RemapRedOne; _originalShakeGreen = ShakeGreen; _originalRemapGreenZero = RemapGreenZero; _originalRemapGreenOne = RemapGreenOne; _originalShakeBlue = ShakeBlue; _originalRemapBlueZero = RemapBlueZero; _originalRemapBlueOne = RemapBlueOne; } if (!OnlyUseShakerValues) { TimescaleMode = timescaleMode; ShakeDuration = duration; RelativeValues = relativeValues; ShakeRed = shakeRed; RemapRedZero = remapRedZero; RemapRedOne = remapRedOne; ShakeGreen = shakeGreen; RemapGreenZero = remapGreenZero; RemapGreenOne = remapGreenOne; ShakeBlue = shakeBlue; RemapBlueZero = remapBlueZero; RemapBlueOne = remapBlueOne; ForwardDirection = forwardDirection; } Play(); } /// /// Resets the target's values /// protected override void ResetTargetValues() { base.ResetTargetValues(); _channelMixer.redOutRedIn.Override(_initialRed); _channelMixer.greenOutGreenIn.Override(_initialGreen); _channelMixer.blueOutBlueIn.Override(_initialBlue); } /// /// Resets the shaker's values /// protected override void ResetShakerValues() { base.ResetShakerValues(); ShakeDuration = _originalShakeDuration; RelativeValues = _originalRelativeValues; ShakeRed = _originalShakeRed; RemapRedZero = _originalRemapRedZero; RemapRedOne = _originalRemapRedOne; ShakeGreen = _originalShakeGreen; RemapGreenZero = _originalRemapGreenZero; RemapGreenOne = _originalRemapGreenOne; ShakeBlue = _originalShakeBlue; RemapBlueZero = _originalRemapBlueZero; RemapBlueOne = _originalRemapBlueOne; } /// /// Starts listening for events /// public override void StartListening() { base.StartListening(); MMChannelMixerShakeEvent_URP.Register(OnMMChannelMixerShakeEvent); } /// /// Stops listening for events /// public override void StopListening() { base.StopListening(); MMChannelMixerShakeEvent_URP.Unregister(OnMMChannelMixerShakeEvent); } #endif } /// /// An event used to trigger vignette shakes /// public struct MMChannelMixerShakeEvent_URP { static private event Delegate OnEvent; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void RuntimeInitialization() { OnEvent = null; } static public void Register(Delegate callback) { OnEvent += callback; } static public void Unregister(Delegate callback) { OnEvent -= callback; } public delegate void Delegate( AnimationCurve shakeRed, float remapRedZero, float remapRedOne, AnimationCurve shakeGreen, float remapGreenZero, float remapGreenOne, AnimationCurve shakeBlue, float remapBlueZero, float remapBlueOne, float duration, bool relativeValues = false, float attenuation = 1.0f, MMChannelData channelData = null, bool resetShakerValuesAfterShake = true, bool resetTargetValuesAfterShake = true, bool forwardDirection = true, TimescaleModes timescaleMode = TimescaleModes.Scaled, bool stop = false, bool restore = false); static public void Trigger( AnimationCurve shakeRed, float remapRedZero, float remapRedOne, AnimationCurve shakeGreen, float remapGreenZero, float remapGreenOne, AnimationCurve shakeBlue, float remapBlueZero, float remapBlueOne, float duration, bool relativeValues = false, float attenuation = 1.0f, MMChannelData channelData = null, bool resetShakerValuesAfterShake = true, bool resetTargetValuesAfterShake = true, bool forwardDirection = true, TimescaleModes timescaleMode = TimescaleModes.Scaled, bool stop = false, bool restore = false) { OnEvent?.Invoke(shakeRed, remapRedZero, remapRedOne, shakeGreen, remapGreenZero, remapGreenOne, shakeBlue, remapBlueZero, remapBlueOne, duration, relativeValues, attenuation, channelData, resetShakerValuesAfterShake, resetTargetValuesAfterShake, forwardDirection, timescaleMode, stop, restore); } } }