using UnityEngine;
using UnityEngine.Rendering;
using MoreMountains.Feedbacks;
using MoreMountains.Tools;
#if MM_HDRP
using UnityEngine.Rendering.HighDefinition;
#endif
namespace MoreMountains.FeedbacksForThirdParty
{
///
/// Add this class to a Camera with a HDRP exposure post processing and it'll be able to "shake" its values by getting events
///
#if MM_HDRP
[RequireComponent(typeof(Volume))]
#endif
[AddComponentMenu("More Mountains/Feedbacks/Shakers/PostProcessing/MMExposureShaker_HDRP")]
public class MMExposureShaker_HDRP : MMShaker
{
[MMInspectorGroup("Exposure Intensity", true, 46)]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeIntensity = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeFixedExposure = 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")]
public float RemapFixedExposureZero = 8.5f;
/// the value to remap the curve's 1 to
[Tooltip("the value to remap the curve's 1 to")]
public float RemapFixedExposureOne = 6f;
#if MM_HDRP
protected Volume _volume;
protected Exposure _exposure;
protected float _initialFixedExposure;
protected float _originalShakeDuration;
protected AnimationCurve _originalShakeFixedExposure;
protected float _originalRemapFixedExposureZero;
protected float _originalRemapFixedExposureOne;
protected bool _originalRelativeFixedExposure;
///
/// On init we initialize our values
///
protected override void Initialization()
{
base.Initialization();
_volume = this.gameObject.GetComponent();
_volume.profile.TryGet(out _exposure);
}
///
/// Shakes values over time
///
protected override void Shake()
{
float newValue = ShakeFloat(ShakeFixedExposure, RemapFixedExposureZero, RemapFixedExposureOne, RelativeIntensity, _initialFixedExposure);
_exposure.fixedExposure.Override(newValue);
}
///
/// Collects initial values on the target
///
protected override void GrabInitialValues()
{
_initialFixedExposure = _exposure.fixedExposure.value;
}
///
/// When we get the appropriate event, we trigger a shake
///
///
///
///
///
///
///
public virtual void OnExposureShakeEvent(AnimationCurve intensity, float duration, float remapMin, float remapMax, bool relativeIntensity = 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;
_originalShakeFixedExposure = ShakeFixedExposure;
_originalRemapFixedExposureZero = RemapFixedExposureZero;
_originalRemapFixedExposureOne = RemapFixedExposureOne;
_originalRelativeFixedExposure = RelativeIntensity;
}
if (!OnlyUseShakerValues)
{
TimescaleMode = timescaleMode;
ShakeDuration = duration;
ShakeFixedExposure = intensity;
RemapFixedExposureZero = remapMin * attenuation;
RemapFixedExposureOne = remapMax * attenuation;
RelativeIntensity = relativeIntensity;
ForwardDirection = forwardDirection;
}
Play();
}
///
/// Resets the target's values
///
protected override void ResetTargetValues()
{
base.ResetTargetValues();
_exposure.fixedExposure.Override(_initialFixedExposure);
}
///
/// Resets the shaker's values
///
protected override void ResetShakerValues()
{
base.ResetShakerValues();
ShakeDuration = _originalShakeDuration;
ShakeFixedExposure = _originalShakeFixedExposure;
RemapFixedExposureZero = _originalRemapFixedExposureZero;
RemapFixedExposureOne = _originalRemapFixedExposureOne;
RelativeIntensity = _originalRelativeFixedExposure;
}
///
/// Starts listening for events
///
public override void StartListening()
{
base.StartListening();
MMExposureShakeEvent_HDRP.Register(OnExposureShakeEvent);
}
///
/// Stops listening for events
///
public override void StopListening()
{
base.StopListening();
MMExposureShakeEvent_HDRP.Unregister(OnExposureShakeEvent);
}
#endif
}
///
/// An event used to trigger exposure shakes
///
public struct MMExposureShakeEvent_HDRP
{
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 fixedExposure, float duration, float remapMin, float remapMax, bool relativeFixedExposure = 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 fixedExposure, float duration, float remapMin, float remapMax, bool relativeFixedExposure = 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(fixedExposure, duration, remapMin, remapMax, relativeFixedExposure, attenuation, channelData, resetShakerValuesAfterShake,
resetTargetValuesAfterShake, forwardDirection, timescaleMode, stop, restore);
}
}
}