chore: initial commit
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
using UnityEngine;
|
||||
using MoreMountains.Feedbacks;
|
||||
#if MM_POSTPROCESSING
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
#endif
|
||||
|
||||
namespace MoreMountains.FeedbacksForThirdParty
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this class to have a global PP volume auto blend its weight on cue, between a start and end values
|
||||
/// </summary>
|
||||
[AddComponentMenu("More Mountains/Feedbacks/Shakers/PostProcessing/MMGlobalPostProcessingVolumeAutoBlend")]
|
||||
#if MM_POSTPROCESSING
|
||||
[RequireComponent(typeof(PostProcessVolume))]
|
||||
#endif
|
||||
public class MMGlobalPostProcessingVolumeAutoBlend : MonoBehaviour
|
||||
{
|
||||
/// the possible timescales this blend can operate on
|
||||
public enum TimeScales { Scaled, Unscaled }
|
||||
/// the possible blend trigger modes
|
||||
public enum BlendTriggerModes { OnEnable, Script }
|
||||
|
||||
[Header("Blend")]
|
||||
/// the trigger mode for this MMGlobalPostProcessingVolumeAutoBlend
|
||||
/// Start : will play automatically on enable
|
||||
[Tooltip("the trigger mode for this MMGlobalPostProcessingVolumeAutoBlend")]
|
||||
public BlendTriggerModes BlendTriggerMode = BlendTriggerModes.OnEnable;
|
||||
/// the duration of the blend (in seconds)
|
||||
[Tooltip("the duration of the blend (in seconds)")]
|
||||
public float BlendDuration = 1f;
|
||||
/// the curve to use to blend
|
||||
[Tooltip("the curve to use to blend")]
|
||||
public AnimationCurve Curve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1f));
|
||||
|
||||
[Header("Weight")]
|
||||
/// the weight at the start of the blend
|
||||
[Tooltip("the weight at the start of the blend")]
|
||||
[Range(0f, 1f)]
|
||||
public float InitialWeight = 0f;
|
||||
/// the desired weight at the end of the blend
|
||||
[Tooltip("the desired weight at the end of the blend")]
|
||||
[Range(0f, 1f)]
|
||||
public float FinalWeight = 1f;
|
||||
|
||||
[Header("Behaviour")]
|
||||
/// the timescale to operate on
|
||||
[Tooltip("the timescale to operate on")]
|
||||
public TimeScales TimeScale = TimeScales.Unscaled;
|
||||
/// whether or not the associated volume should be disabled at 0
|
||||
[Tooltip("whether or not the associated volume should be disabled at 0")]
|
||||
public bool DisableVolumeOnZeroWeight = true;
|
||||
/// whether or not this blender should disable itself at 0
|
||||
[Tooltip("whether or not this blender should disable itself at 0")]
|
||||
public bool DisableSelfAfterEnd = true;
|
||||
/// whether or not this blender can be interrupted
|
||||
[Tooltip("whether or not this blender can be interrupted")]
|
||||
public bool Interruptable = true;
|
||||
/// whether or not this blender should pick the current value as its starting point
|
||||
[Tooltip("whether or not this blender should pick the current value as its starting point")]
|
||||
public bool StartFromCurrentValue = true;
|
||||
/// reset to initial value on end
|
||||
[Tooltip("reset to initial value on end ")]
|
||||
public bool ResetToInitialValueOnEnd = false;
|
||||
|
||||
[Header("Tests")]
|
||||
/// test blend button
|
||||
[Tooltip("test blend button")]
|
||||
[MMFInspectorButton("Blend")]
|
||||
public bool TestBlend;
|
||||
/// test blend back button
|
||||
[Tooltip("test blend back button")]
|
||||
[MMFInspectorButton("BlendBack")]
|
||||
public bool TestBlendBackwards;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the correct timescale based on the chosen settings
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected float GetTime()
|
||||
{
|
||||
return (TimeScale == TimeScales.Unscaled) ? Time.unscaledTime : Time.time;
|
||||
}
|
||||
|
||||
protected float _initial;
|
||||
protected float _destination;
|
||||
protected float _startTime;
|
||||
protected bool _blending = false;
|
||||
#if MM_POSTPROCESSING
|
||||
protected PostProcessVolume _volume;
|
||||
|
||||
/// <summary>
|
||||
/// On Awake we store our volume
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
#if MM_POSTPROCESSING
|
||||
_volume = this.gameObject.GetComponent<PostProcessVolume>();
|
||||
_volume.weight = InitialWeight;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On start we start blending if needed
|
||||
/// </summary>
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
if ((BlendTriggerMode == BlendTriggerModes.OnEnable) && !_blending)
|
||||
{
|
||||
Blend();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blends the volume's weight from the initial value to the final one
|
||||
/// </summary>
|
||||
public virtual void Blend()
|
||||
{
|
||||
if (_blending && !Interruptable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_initial = StartFromCurrentValue ? _volume.weight : InitialWeight;
|
||||
_destination = FinalWeight;
|
||||
StartBlending();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blends the volume's weight from the final value to the initial one
|
||||
/// </summary>
|
||||
public virtual void BlendBack()
|
||||
{
|
||||
if (_blending && !Interruptable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_initial = StartFromCurrentValue ? _volume.weight : FinalWeight;
|
||||
_destination = InitialWeight;
|
||||
StartBlending();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method used to start blending
|
||||
/// </summary>
|
||||
protected virtual void StartBlending()
|
||||
{
|
||||
_startTime = GetTime();
|
||||
_blending = true;
|
||||
this.enabled = true;
|
||||
if (DisableVolumeOnZeroWeight)
|
||||
{
|
||||
_volume.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops any blending that may be in progress
|
||||
/// </summary>
|
||||
public virtual void StopBlending()
|
||||
{
|
||||
_blending = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// On update, processes the blend if needed
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (!_blending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float timeElapsed = (GetTime() - _startTime);
|
||||
if (timeElapsed < BlendDuration)
|
||||
{
|
||||
float remapped = MMFeedbacksHelpers.Remap(timeElapsed, 0f, BlendDuration, 0f, 1f);
|
||||
_volume.weight = Mathf.LerpUnclamped(_initial, _destination, Curve.Evaluate(remapped));
|
||||
}
|
||||
else
|
||||
{
|
||||
// after end is reached
|
||||
_volume.weight = ResetToInitialValueOnEnd ? _initial : _destination;
|
||||
_blending = false;
|
||||
if (DisableVolumeOnZeroWeight && (_volume.weight == 0f))
|
||||
{
|
||||
_volume.enabled = false;
|
||||
}
|
||||
if (DisableSelfAfterEnd)
|
||||
{
|
||||
this.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RestoreInitialValues()
|
||||
{
|
||||
_volume.weight = _initial;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d073f09c04a999428a9149986800bfb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
using MoreMountains.Feedbacks;
|
||||
using MoreMountains.Tools;
|
||||
using UnityEngine;
|
||||
#if MM_POSTPROCESSING
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
#endif
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace MoreMountains.FeedbacksForThirdParty
|
||||
{
|
||||
public class MMPostProcessingHelpers : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR && MM_POSTPROCESSING
|
||||
public static void GetOrCreateVolume<T, U>(MMF_Player owner, string feedbackName) where T:PostProcessEffectSettings where U:MMShaker
|
||||
{
|
||||
string additions = owner.name + " "+feedbackName+" feedback automatic shaker setup : ";
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Debug.LogWarning("Automatic shaker setup is only available outside of play mode.");
|
||||
return;
|
||||
}
|
||||
|
||||
// looks for a post process layer
|
||||
PostProcessLayer postProcessLayer = Object.FindObjectOfType<PostProcessLayer>();
|
||||
if (postProcessLayer == null)
|
||||
{
|
||||
postProcessLayer = Camera.main.gameObject.AddComponent<PostProcessLayer>();
|
||||
postProcessLayer.volumeLayer = -1;
|
||||
additions += "Added a PostProcessLayer component to the "+Camera.main.name+" camera. ";
|
||||
}
|
||||
|
||||
// looks for a post processing volume
|
||||
PostProcessVolume volume = (PostProcessVolume)Object.FindObjectOfType(typeof(PostProcessVolume));
|
||||
if (volume == null)
|
||||
{
|
||||
GameObject postProcessingObject = GameObject.Instantiate(Resources.Load<GameObject>("MMDefaultPostProcessingVolume"));
|
||||
volume = postProcessingObject.GetComponent<PostProcessVolume>();
|
||||
additions += "Added a PostProcessingVolume to the scene. ";
|
||||
}
|
||||
|
||||
// looks for a setting on the volume
|
||||
T effect;
|
||||
if (!volume.sharedProfile.TryGetSettings(out effect))
|
||||
{
|
||||
effect = volume.sharedProfile.AddSettings<T>();
|
||||
AssetDatabase.AddObjectToAsset(effect, volume.sharedProfile);
|
||||
EditorUtility.SetDirty(volume.sharedProfile);
|
||||
AssetDatabase.SaveAssets();
|
||||
additions += "Added a "+feedbackName+" post process effect to the "+volume.gameObject.name+" Post Process Volume. ";
|
||||
}
|
||||
|
||||
// looks for a matching shaker
|
||||
U shaker = volume.GetComponent<U>();
|
||||
if (shaker == null)
|
||||
{
|
||||
shaker = volume.gameObject.AddComponent<U>();
|
||||
additions += "Added a "+feedbackName+" Shaker to the "+volume.gameObject.name+" Post Process Volume. ";
|
||||
}
|
||||
|
||||
MMDebug.DebugLogInfo( additions + "You're all set.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c90af9401f16038488cbc1a21e79de15
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user