using UnityEngine;
#if MM_CINEMACHINE
using Cinemachine;
#endif
using MoreMountains.Feedbacks;
using MoreMountains.Tools;
namespace MoreMountains.FeedbacksForThirdParty
{
///
/// Add this to a Cinemachine virtual camera and it'll let you control its field of view over time, can be piloted by a MMFeedbackCameraFieldOfView
///
[AddComponentMenu("More Mountains/Feedbacks/Shakers/Cinemachine/MMCinemachineFieldOfViewShaker")]
#if MM_CINEMACHINE
[RequireComponent(typeof(CinemachineVirtualCamera))]
#endif
public class MMCinemachineFieldOfViewShaker : MMShaker
{
[MMInspectorGroup("Field of view", true, 41)]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeFieldOfView = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeFieldOfView = 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(0f, 179f)]
public float RemapFieldOfViewZero = 60f;
/// the value to remap the curve's 1 to
[Tooltip("the value to remap the curve's 1 to")]
[Range(0f, 179f)]
public float RemapFieldOfViewOne = 120f;
#if MM_CINEMACHINE
protected CinemachineVirtualCamera _targetCamera;
protected float _initialFieldOfView;
protected float _originalShakeDuration;
protected bool _originalRelativeFieldOfView;
protected AnimationCurve _originalShakeFieldOfView;
protected float _originalRemapFieldOfViewZero;
protected float _originalRemapFieldOfViewOne;
///
/// On init we initialize our values
///
protected override void Initialization()
{
base.Initialization();
_targetCamera = this.gameObject.GetComponent();
}
///
/// When that shaker gets added, we initialize its shake duration
///
protected virtual void Reset()
{
ShakeDuration = 0.5f;
}
///
/// Shakes values over time
///
protected override void Shake()
{
float newFieldOfView = ShakeFloat(ShakeFieldOfView, RemapFieldOfViewZero, RemapFieldOfViewOne, RelativeFieldOfView, _initialFieldOfView);
_targetCamera.m_Lens.FieldOfView = newFieldOfView;
}
///
/// Collects initial values on the target
///
protected override void GrabInitialValues()
{
_initialFieldOfView = _targetCamera.m_Lens.FieldOfView;
}
///
/// When we get the appropriate event, we trigger a shake
///
///
///
///
///
///
///
public virtual void OnMMCameraFieldOfViewShakeEvent(AnimationCurve distortionCurve, float duration, float remapMin, float remapMax, bool relativeDistortion = false,
float feedbacksIntensity = 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))
{
return;
}
if (stop)
{
Stop();
return;
}
if (restore)
{
ResetTargetValues();
return;
}
if (!Interruptible && Shaking)
{
return;
}
_resetShakerValuesAfterShake = resetShakerValuesAfterShake;
_resetTargetValuesAfterShake = resetTargetValuesAfterShake;
if (resetShakerValuesAfterShake)
{
_originalShakeDuration = ShakeDuration;
_originalShakeFieldOfView = ShakeFieldOfView;
_originalRemapFieldOfViewZero = RemapFieldOfViewZero;
_originalRemapFieldOfViewOne = RemapFieldOfViewOne;
_originalRelativeFieldOfView = RelativeFieldOfView;
}
if (!OnlyUseShakerValues)
{
TimescaleMode = timescaleMode;
ShakeDuration = duration;
ShakeFieldOfView = distortionCurve;
RemapFieldOfViewZero = remapMin * feedbacksIntensity;
RemapFieldOfViewOne = remapMax * feedbacksIntensity;
RelativeFieldOfView = relativeDistortion;
ForwardDirection = forwardDirection;
}
Play();
}
///
/// Resets the target's values
///
protected override void ResetTargetValues()
{
base.ResetTargetValues();
_targetCamera.m_Lens.FieldOfView = _initialFieldOfView;
}
///
/// Resets the shaker's values
///
protected override void ResetShakerValues()
{
base.ResetShakerValues();
ShakeDuration = _originalShakeDuration;
ShakeFieldOfView = _originalShakeFieldOfView;
RemapFieldOfViewZero = _originalRemapFieldOfViewZero;
RemapFieldOfViewOne = _originalRemapFieldOfViewOne;
RelativeFieldOfView = _originalRelativeFieldOfView;
}
///
/// Starts listening for events
///
public override void StartListening()
{
base.StartListening();
MMCameraFieldOfViewShakeEvent.Register(OnMMCameraFieldOfViewShakeEvent);
}
///
/// Stops listening for events
///
public override void StopListening()
{
base.StopListening();
MMCameraFieldOfViewShakeEvent.Unregister(OnMMCameraFieldOfViewShakeEvent);
}
#endif
}
}