Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 2ba1c94b88
commit ee9aee0a1b
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 957ed344f5281364f9d49b1af5d9b31c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,271 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// A feedback used to trigger an animation (bool, int, float or trigger) on the associated animator, with or without randomness
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will allow you to send to an animator (bound in its inspector) a bool, int, float or trigger parameter, allowing you to trigger an animation, with or without randomness.")]
[FeedbackPath("GameObject/Animation")]
public class MMFeedbackAnimation : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the possible modes that pilot triggers
public enum TriggerModes { SetTrigger, ResetTrigger }
/// the possible ways to set a value
public enum ValueModes { None, Constant, Random, Incremental }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
[Header("Animation")]
/// the animator whose parameters you want to update
[Tooltip("the animator whose parameters you want to update")]
public Animator BoundAnimator;
[Header("Trigger")]
/// if this is true, will update the specified trigger parameter
[Tooltip("if this is true, will update the specified trigger parameter")]
public bool UpdateTrigger = false;
/// the selected mode to interact with this trigger
[Tooltip("the selected mode to interact with this trigger")]
[MMFCondition("UpdateTrigger", true)]
public TriggerModes TriggerMode = TriggerModes.SetTrigger;
/// the trigger animator parameter to, well, trigger when the feedback is played
[Tooltip("the trigger animator parameter to, well, trigger when the feedback is played")]
[MMFCondition("UpdateTrigger", true)]
public string TriggerParameterName;
[Header("Random Trigger")]
/// if this is true, will update a random trigger parameter, picked from the list below
[Tooltip("if this is true, will update a random trigger parameter, picked from the list below")]
public bool UpdateRandomTrigger = false;
/// the selected mode to interact with this trigger
[Tooltip("the selected mode to interact with this trigger")]
[MMFCondition("UpdateRandomTrigger", true)]
public TriggerModes RandomTriggerMode = TriggerModes.SetTrigger;
/// the trigger animator parameters to trigger at random when the feedback is played
[Tooltip("the trigger animator parameters to trigger at random when the feedback is played")]
public List<string> RandomTriggerParameterNames;
[Header("Bool")]
/// if this is true, will update the specified bool parameter
[Tooltip("if this is true, will update the specified bool parameter")]
public bool UpdateBool = false;
/// the bool parameter to turn true when the feedback gets played
[Tooltip("the bool parameter to turn true when the feedback gets played")]
[MMFCondition("UpdateBool", true)]
public string BoolParameterName;
/// when in bool mode, whether to set the bool parameter to true or false
[Tooltip("when in bool mode, whether to set the bool parameter to true or false")]
[MMFCondition("UpdateBool", true)]
public bool BoolParameterValue = true;
[Header("Random Bool")]
/// if this is true, will update a random bool parameter picked from the list below
[Tooltip("if this is true, will update a random bool parameter picked from the list below")]
public bool UpdateRandomBool = false;
/// when in bool mode, whether to set the bool parameter to true or false
[Tooltip("when in bool mode, whether to set the bool parameter to true or false")]
[MMFCondition("UpdateRandomBool", true)]
public bool RandomBoolParameterValue = true;
/// the bool parameter to turn true when the feedback gets played
[Tooltip("the bool parameter to turn true when the feedback gets played")]
public List<string> RandomBoolParameterNames;
[Header("Int")]
/// the int parameter to turn true when the feedback gets played
[Tooltip("the int parameter to turn true when the feedback gets played")]
public ValueModes IntValueMode = ValueModes.None;
/// the int parameter to turn true when the feedback gets played
[Tooltip("the int parameter to turn true when the feedback gets played")]
[MMFEnumCondition("IntValueMode", (int)ValueModes.Constant, (int)ValueModes.Random, (int)ValueModes.Incremental)]
public string IntParameterName;
/// the value to set to that int parameter
[Tooltip("the value to set to that int parameter")]
[MMFEnumCondition("IntValueMode", (int)ValueModes.Constant)]
public int IntValue;
/// the min value (inclusive) to set at random to that int parameter
[Tooltip("the min value (inclusive) to set at random to that int parameter")]
[MMFEnumCondition("IntValueMode", (int)ValueModes.Random)]
public int IntValueMin;
/// the max value (exclusive) to set at random to that int parameter
[Tooltip("the max value (exclusive) to set at random to that int parameter")]
[MMFEnumCondition("IntValueMode", (int)ValueModes.Random)]
public int IntValueMax = 5;
/// the value to increment that int parameter by
[Tooltip("the value to increment that int parameter by")]
[MMFEnumCondition("IntValueMode", (int)ValueModes.Incremental)]
public int IntIncrement = 1;
[Header("Float")]
/// the Float parameter to turn true when the feedback gets played
[Tooltip("the Float parameter to turn true when the feedback gets played")]
public ValueModes FloatValueMode = ValueModes.None;
/// the float parameter to turn true when the feedback gets played
[Tooltip("the float parameter to turn true when the feedback gets played")]
[MMFEnumCondition("FloatValueMode", (int)ValueModes.Constant, (int)ValueModes.Random, (int)ValueModes.Incremental)]
public string FloatParameterName;
/// the value to set to that float parameter
[Tooltip("the value to set to that float parameter")]
[MMFEnumCondition("FloatValueMode", (int)ValueModes.Constant)]
public float FloatValue;
/// the min value (inclusive) to set at random to that float parameter
[Tooltip("the min value (inclusive) to set at random to that float parameter")]
[MMFEnumCondition("FloatValueMode", (int)ValueModes.Random)]
public float FloatValueMin;
/// the max value (exclusive) to set at random to that float parameter
[Tooltip("the max value (exclusive) to set at random to that float parameter")]
[MMFEnumCondition("FloatValueMode", (int)ValueModes.Random)]
public float FloatValueMax = 5;
/// the value to increment that float parameter by
[Tooltip("the value to increment that float parameter by")]
[MMFEnumCondition("FloatValueMode", (int)ValueModes.Incremental)]
public float FloatIncrement = 1;
protected int _triggerParameter;
protected int _boolParameter;
protected int _intParameter;
protected int _floatParameter;
protected List<int> _randomTriggerParameters;
protected List<int> _randomBoolParameters;
/// <summary>
/// Custom Init
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
_triggerParameter = Animator.StringToHash(TriggerParameterName);
_boolParameter = Animator.StringToHash(BoolParameterName);
_intParameter = Animator.StringToHash(IntParameterName);
_floatParameter = Animator.StringToHash(FloatParameterName);
_randomTriggerParameters = new List<int>();
foreach (string name in RandomTriggerParameterNames)
{
_randomTriggerParameters.Add(Animator.StringToHash(name));
}
_randomBoolParameters = new List<int>();
foreach (string name in RandomBoolParameterNames)
{
_randomBoolParameters.Add(Animator.StringToHash(name));
}
}
/// <summary>
/// On Play, checks if an animator is bound and triggers parameters
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (BoundAnimator == null)
{
Debug.LogWarning("No animator was set for " + this.name);
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
if (UpdateTrigger)
{
if (TriggerMode == TriggerModes.SetTrigger)
{
BoundAnimator.SetTrigger(_triggerParameter);
}
if (TriggerMode == TriggerModes.ResetTrigger)
{
BoundAnimator.ResetTrigger(_triggerParameter);
}
}
if (UpdateRandomTrigger)
{
int randomParameter = _randomTriggerParameters[Random.Range(0, _randomTriggerParameters.Count)];
if (RandomTriggerMode == TriggerModes.SetTrigger)
{
BoundAnimator.SetTrigger(randomParameter);
}
if (RandomTriggerMode == TriggerModes.ResetTrigger)
{
BoundAnimator.ResetTrigger(randomParameter);
}
}
if (UpdateBool)
{
BoundAnimator.SetBool(_boolParameter, BoolParameterValue);
}
if (UpdateRandomBool)
{
int randomParameter = _randomBoolParameters[Random.Range(0, _randomBoolParameters.Count)];
BoundAnimator.SetBool(randomParameter, RandomBoolParameterValue);
}
switch (IntValueMode)
{
case ValueModes.Constant:
BoundAnimator.SetInteger(_intParameter, IntValue);
break;
case ValueModes.Incremental:
int newValue = BoundAnimator.GetInteger(_intParameter) + IntIncrement;
BoundAnimator.SetInteger(_intParameter, newValue);
break;
case ValueModes.Random:
int randomValue = Random.Range(IntValueMin, IntValueMax);
BoundAnimator.SetInteger(_intParameter, randomValue);
break;
}
switch (FloatValueMode)
{
case ValueModes.Constant:
BoundAnimator.SetFloat(_floatParameter, FloatValue * intensityMultiplier);
break;
case ValueModes.Incremental:
float newValue = BoundAnimator.GetFloat(_floatParameter) + FloatIncrement * intensityMultiplier;
BoundAnimator.SetFloat(_floatParameter, newValue);
break;
case ValueModes.Random:
float randomValue = Random.Range(FloatValueMin, FloatValueMax) * intensityMultiplier;
BoundAnimator.SetFloat(_floatParameter, randomValue);
break;
}
}
/// <summary>
/// On stop, turns the bool parameter to false
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !UpdateBool || !FeedbackTypeAuthorized)
{
return;
}
BoundAnimator.SetBool(_boolParameter, false);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b1c6a190d064b7642bc4c5b64bbcd3c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
using System.Collections;
using System.Collections.Generic;
using MoreMountains.Tools;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you change the speed of a target animator, either once, or instantly and then reset it, or interpolate it over time
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you change the speed of a target animator, either once, or instantly and then reset it, or interpolate it over time")]
[FeedbackPath("GameObject/Animator Speed")]
public class MMFeedbackAnimatorSpeed : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
public enum Modes { Once, InstantThenReset, OverTime }
public virtual float GetTime() { return (Timing.TimescaleMode == TimescaleModes.Scaled) ? Time.time : Time.unscaledTime; }
public virtual float GetDeltaTime() { return (Timing.TimescaleMode == TimescaleModes.Scaled) ? Time.deltaTime : Time.unscaledDeltaTime; }
[Header("Animation")]
/// the animator whose parameters you want to update
[Tooltip("the animator whose parameters you want to update")]
public Animator BoundAnimator;
[Header("Speed")]
/// whether to change the speed of the target animator once, instantly and reset it later, or have it change over time
[Tooltip("whether to change the speed of the target animator once, instantly and reset it later, or have it change over time")]
public Modes Mode = Modes.Once;
/// the new minimum speed at which to set the animator - value will be randomized between min and max
[Tooltip("the new minimum speed at which to set the animator - value will be randomized between min and max")]
public float NewSpeedMin = 0f;
/// the new maximum speed at which to set the animator - value will be randomized between min and max
[Tooltip("the new maximum speed at which to set the animator - value will be randomized between min and max")]
public float NewSpeedMax = 0f;
/// when in instant then reset or over time modes, the duration of the effect
[Tooltip("when in instant then reset or over time modes, the duration of the effect")]
[MMFEnumCondition("Mode", (int)Modes.InstantThenReset, (int)Modes.OverTime)]
public float Duration = 1f;
/// when in over time mode, the curve against which to evaluate the new speed
[Tooltip("when in over time mode, the curve against which to evaluate the new speed")]
[MMFEnumCondition("Mode", (int)Modes.OverTime)]
public AnimationCurve Curve = new AnimationCurve(new Keyframe(0, 0f), new Keyframe(0.5f, 1f), new Keyframe(1, 0f));
protected Coroutine _coroutine;
protected float _initialSpeed;
protected float _startedAt;
/// <summary>
/// On Play, checks if an animator is bound and triggers parameters
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (BoundAnimator == null)
{
Debug.LogWarning("No animator was set for " + this.name);
return;
}
if (!IsPlaying)
{
_initialSpeed = BoundAnimator.speed;
}
if (Mode == Modes.Once)
{
BoundAnimator.speed = DetermineNewSpeed();
}
else
{
_coroutine = StartCoroutine(ChangeSpeedCo());
}
}
/// <summary>
/// A coroutine used in ForDuration mode
/// </summary>
/// <returns></returns>
protected virtual IEnumerator ChangeSpeedCo()
{
if (Mode == Modes.InstantThenReset)
{
IsPlaying = true;
BoundAnimator.speed = DetermineNewSpeed();
yield return MMCoroutine.WaitFor(Duration);
BoundAnimator.speed = _initialSpeed;
IsPlaying = false;
}
else if (Mode == Modes.OverTime)
{
IsPlaying = true;
_startedAt = GetTime();
float newTargetSpeed = DetermineNewSpeed();
while (GetTime() - _startedAt < Duration)
{
float time = MMFeedbacksHelpers.Remap(GetTime() - _startedAt, 0f, Duration, 0f, 1f);
float t = Curve.Evaluate(time);
BoundAnimator.speed = Mathf.Max(0f, MMFeedbacksHelpers.Remap(t, 0f, 1f, _initialSpeed, newTargetSpeed));
yield return null;
}
BoundAnimator.speed = _initialSpeed;
IsPlaying = false;
}
}
/// <summary>
/// Determines the new speed for the target animator
/// </summary>
/// <returns></returns>
protected virtual float DetermineNewSpeed()
{
return Mathf.Abs(Random.Range(NewSpeedMin, NewSpeedMax));
}
/// <summary>
/// On stop, turns the bool parameter to false
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (_coroutine != null)
{
StopCoroutine(_coroutine);
}
BoundAnimator.speed = _initialSpeed;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0328008366681704fb2929076642a671
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the distortion level of a distortion filter. You'll need a MMAudioFilterDistortionShaker on the filter.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/Audio Filter Distortion")]
[FeedbackHelp("This feedback lets you control a distortion audio filter over time. You'll need a MMAudioFilterDistortionShaker on the filter.")]
public class MMFeedbackAudioFilterDistortion : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Distortion Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Distortion")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeDistortion = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeDistortion = 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, 1f)]
public float RemapDistortionZero = 0f;
/// the value to remap the curve's 1 to
[Tooltip("the value to remap the curve's 1 to")]
[Range(0f, 1f)]
public float RemapDistortionOne = 1f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
float remapZero = 0f;
float remapOne = 0f;
if (!Timing.ConstantIntensity)
{
remapZero = RemapDistortionZero * intensityMultiplier;
remapOne = RemapDistortionOne * intensityMultiplier;
}
MMAudioFilterDistortionShakeEvent.Trigger(ShakeDistortion, FeedbackDuration, remapZero, remapOne, RelativeDistortion,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
base.CustomStopFeedback(position, feedbacksIntensity);
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
MMAudioFilterDistortionShakeEvent.Trigger(ShakeDistortion, FeedbackDuration, 0f,0f, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 03df03e041aea9744949f294cfb94219
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the wetmix level of an echo filter. You'll need a MMAudioFilterEchoShaker on your filter.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/Audio Filter Echo")]
[FeedbackHelp("This feedback lets you control an echo audio filter's wet mix value over time. You'll need a MMAudioFilterEchoShaker on your filter.")]
public class MMFeedbackAudioFilterEcho : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Echo Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Echo")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeEcho = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeEcho = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0));
/// the value to remap the curve's 0 to
[Range(0f, 1f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapEchoZero = 0f;
/// the value to remap the curve's 1 to
[Range(0f, 1f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapEchoOne = 1f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioFilterEchoShakeEvent.Trigger(ShakeEcho, FeedbackDuration, RemapEchoZero, RemapEchoOne, RelativeEcho,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioFilterEchoShakeEvent.Trigger(ShakeEcho, FeedbackDuration, RemapEchoZero, RemapEchoOne, RelativeEcho, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cd6e430a4ad7c534bacc6f892997853b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the cutoff frequency of a high pass filter. You'll need a MMAudioFilterHighPassShaker on your filter.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/Audio Filter High Pass")]
[FeedbackHelp("This feedback lets you control a high pass audio filter over time. You'll need a MMAudioFilterHighPassShaker on your filter.")]
public class MMFeedbackAudioFilterHighPass : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("High Pass Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("High Pass")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeHighPass = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeHighPass = new AnimationCurve(new Keyframe(0, 0f), new Keyframe(0.5f, 1f), new Keyframe(1, 0f));
/// the value to remap the curve's 0 to
[Range(10f, 22000f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapHighPassZero = 0f;
/// the value to remap the curve's 1 to
[Range(10f, 22000f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapHighPassOne = 10000f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioFilterHighPassShakeEvent.Trigger(ShakeHighPass, FeedbackDuration, RemapHighPassZero, RemapHighPassOne, RelativeHighPass,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioFilterHighPassShakeEvent.Trigger(ShakeHighPass, FeedbackDuration, RemapHighPassZero, RemapHighPassOne, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 81be29129249cad49a2c50cf8eb77cc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the cutoff frequency of a low pass filter. You'll need a MMAudioFilterLowPassShaker on your filter.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/Audio Filter Low Pass")]
[FeedbackHelp("This feedback lets you control a low pass audio filter over time. You'll need a MMAudioFilterLowPassShaker on your filter.")]
public class MMFeedbackAudioFilterLowPass : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Low Pass Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Low Pass")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeLowPass = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeLowPass = new AnimationCurve(new Keyframe(0, 1f), new Keyframe(0.5f, 0f), new Keyframe(1, 1f));
/// the value to remap the curve's 0 to
[Range(10f, 22000f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapLowPassZero = 0f;
/// the value to remap the curve's 1 to
[Range(10f, 22000f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapLowPassOne = 10000f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioFilterLowPassShakeEvent.Trigger(ShakeLowPass, FeedbackDuration, RemapLowPassZero, RemapLowPassOne, RelativeLowPass,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioFilterLowPassShakeEvent.Trigger(ShakeLowPass, FeedbackDuration, RemapLowPassZero, RemapLowPassOne, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8643fddc16037544499429bca94fb127
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the reverb level of a reverb filter. You'll need a MMAudioFilterReverbShaker on your filter.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/Audio Filter Reverb")]
[FeedbackHelp("This feedback lets you control a low pass audio filter over time. You'll need a MMAudioFilterReverbShaker on your filter.")]
public class MMFeedbackAudioFilterReverb : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Reverb Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Reverb")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeReverb = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeReverb = new AnimationCurve(new Keyframe(0, 0f), new Keyframe(0.5f, 1f), new Keyframe(1, 0f));
/// the value to remap the curve's 0 to
[Range(-10000f, 2000f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapReverbZero = -10000f;
/// the value to remap the curve's 1 to
[Range(-10000f, 2000f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapReverbOne = 2000f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioFilterReverbShakeEvent.Trigger(ShakeReverb, FeedbackDuration, RemapReverbZero, RemapReverbOne, RelativeReverb,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioFilterReverbShakeEvent.Trigger(ShakeReverb, FeedbackDuration, RemapReverbZero, RemapReverbOne, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09ab3ff8b16aee3418be159df2898b4f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you transition to a target AudioMixer Snapshot over a specified time
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you transition to a target AudioMixer Snapshot over a specified time")]
[FeedbackPath("Audio/AudioMixer Snapshot Transition")]
public class MMFeedbackAudioMixerSnapshotTransition : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.UIColor; } }
#endif
[Header("AudioMixer Snapshot")]
/// the target audio mixer snapshot we want to transition to
[Tooltip("the target audio mixer snapshot we want to transition to")]
public AudioMixerSnapshot TargetSnapshot;
/// the audio mixer snapshot we want to transition from, optional, only needed if you plan to play this feedback in reverse
[Tooltip("the audio mixer snapshot we want to transition from, optional, only needed if you plan to play this feedback in reverse")]
public AudioMixerSnapshot OriginalSnapshot;
/// the duration, in seconds, over which to transition to the selected snapshot
[Tooltip("the duration, in seconds, over which to transition to the selected snapshot")]
public float TransitionDuration = 1f;
/// <summary>
/// On play we transition to the selected snapshot
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (TargetSnapshot == null)
{
return;
}
if (!NormalPlayDirection)
{
if (OriginalSnapshot != null)
{
OriginalSnapshot.TransitionTo(TransitionDuration);
}
else
{
TargetSnapshot.TransitionTo(TransitionDuration);
}
}
else
{
TargetSnapshot.TransitionTo(TransitionDuration);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7dc575a1c09fbe43bcfba7f29d9080b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,153 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
[AddComponentMenu("")]
[FeedbackPath("Audio/AudioSource")]
[FeedbackHelp("This feedback lets you play a target audio source, with some elements at random.")]
public class MMFeedbackAudioSource : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// the possible ways to interact with the audiosource
public enum Modes { Play, Pause, UnPause, Stop }
[Header("AudioSource")]
/// the target audio source to play
[Tooltip("the target audio source to play")]
public AudioSource TargetAudioSource;
/// whether we should play the audio source or stop it or pause it
[Tooltip("whether we should play the audio source or stop it or pause it")]
public Modes Mode = Modes.Play;
[Header("Random Sound")]
/// an array to pick a random sfx from
[Tooltip("an array to pick a random sfx from")]
public AudioClip[] RandomSfx;
[Header("Volume")]
/// the minimum volume to play the sound at
[Tooltip("the minimum volume to play the sound at")]
public float MinVolume = 1f;
/// the maximum volume to play the sound at
[Tooltip("the maximum volume to play the sound at")]
public float MaxVolume = 1f;
[Header("Pitch")]
/// the minimum pitch to play the sound at
[Tooltip("the minimum pitch to play the sound at")]
public float MinPitch = 1f;
/// the maximum pitch to play the sound at
[Tooltip("the maximum pitch to play the sound at")]
public float MaxPitch = 1f;
[Header("Mixer")]
/// the audiomixer to play the sound with (optional)
[Tooltip("the audiomixer to play the sound with (optional)")]
public AudioMixerGroup SfxAudioMixerGroup;
/// the duration of this feedback is the duration of the clip being played
public override float FeedbackDuration { get { return _duration; } set { _duration = value; } }
protected AudioClip _randomClip;
protected float _duration;
/// <summary>
/// Custom init to cache the audiosource if required
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
}
/// <summary>
/// Plays either a random sound or the specified sfx
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
switch(Mode)
{
case Modes.Play:
if (RandomSfx.Length > 0)
{
_randomClip = RandomSfx[Random.Range(0, RandomSfx.Length)];
TargetAudioSource.clip = _randomClip;
}
float volume = Random.Range(MinVolume, MaxVolume) * intensityMultiplier;
float pitch = Random.Range(MinPitch, MaxPitch);
_duration = TargetAudioSource.clip.length;
PlayAudioSource(TargetAudioSource, volume, pitch);
break;
case Modes.Pause:
_duration = 0.1f;
TargetAudioSource.Pause();
break;
case Modes.UnPause:
_duration = 0.1f;
TargetAudioSource.UnPause();
break;
case Modes.Stop:
_duration = 0.1f;
TargetAudioSource.Stop();
break;
}
}
/// <summary>
/// Plays the audiosource at the selected volume and pitch
/// </summary>
/// <param name="audioSource"></param>
/// <param name="volume"></param>
/// <param name="pitch"></param>
protected virtual void PlayAudioSource(AudioSource audioSource, float volume, float pitch)
{
// we set the audio source volume to the one in parameters
audioSource.volume = volume;
audioSource.pitch = pitch;
audioSource.timeSamples = 0;
if (!NormalPlayDirection)
{
audioSource.pitch = -1;
audioSource.timeSamples = audioSource.clip.samples - 1;
}
// we start playing the sound
audioSource.Play();
}
/// <summary>
/// Stops the audiosource from playing
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
public override void Stop(Vector3 position, float feedbacksIntensity = 1.0f)
{
base.Stop(position, feedbacksIntensity);
if (TargetAudioSource != null)
{
TargetAudioSource?.Stop();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fbeb74f1ccfa52540b6fd5784df42533
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the pitch of an AudioSource over time
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/AudioSource Pitch")]
[FeedbackHelp("This feedback lets you control the pitch of a target AudioSource over time.")]
public class MMFeedbackAudioSourcePitch : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Pitch Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Pitch")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativePitch = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve PitchTween = new AnimationCurve(new Keyframe(0, 1f), new Keyframe(0.5f, 0f), new Keyframe(1, 1f));
/// the value to remap the curve's 0 to
[Range(-3f, 3f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapPitchZero = 0f;
/// the value to remap the curve's 1 to
[Range(-3f, 3f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapPitchOne = 1f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioSourcePitchShakeEvent.Trigger(PitchTween, FeedbackDuration, RemapPitchZero, RemapPitchOne, RelativePitch,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioSourcePitchShakeEvent.Trigger(PitchTween, FeedbackDuration, RemapPitchZero, RemapPitchOne, RelativePitch, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3fefab6604749e346b8b98d874e4eef1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the stereo pan of a target AudioSource over time.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/AudioSource Stereo Pan")]
[FeedbackHelp("This feedback lets you control the stereo pan of a target AudioSource over time.")]
public class MMFeedbackAudioSourceStereoPan : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("StereoPan Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("StereoPan")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeStereoPan = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeStereoPan = new AnimationCurve(new Keyframe(0, 0f), new Keyframe(0.3f, 1f), new Keyframe(0.6f, -1f), new Keyframe(1, 0f));
/// the value to remap the curve's 0 to
[Range(-1f, 1f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapStereoPanZero = 0f;
/// the value to remap the curve's 1 to
[Range(-1f, 1f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapStereoPanOne = 1f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioSourceStereoPanShakeEvent.Trigger(ShakeStereoPan, FeedbackDuration, RemapStereoPanZero, RemapStereoPanOne, RelativeStereoPan,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioSourceStereoPanShakeEvent.Trigger(ShakeStereoPan, FeedbackDuration, RemapStereoPanZero, RemapStereoPanOne, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ede03beddc1c11745a76c0e0ff51f4ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the volume of a target AudioSource over time.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Audio/AudioSource Volume")]
[FeedbackHelp("This feedback lets you control the volume of a target AudioSource over time.")]
public class MMFeedbackAudioSourceVolume : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.SoundsColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Volume Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Volume")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeVolume = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve VolumeTween = new AnimationCurve(new Keyframe(0, 1f), new Keyframe(0.5f, 0f), new Keyframe(1, 1f));
/// the value to remap the curve's 0 to
[Range(-1f, 1f)]
[Tooltip("the value to remap the curve's 0 to")]
public float RemapVolumeZero = 0f;
/// the value to remap the curve's 1 to
[Range(-1f, 1f)]
[Tooltip("the value to remap the curve's 1 to")]
public float RemapVolumeOne = 1f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMAudioSourceVolumeShakeEvent.Trigger(VolumeTween, FeedbackDuration, RemapVolumeZero, RemapVolumeOne, RelativeVolume,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMAudioSourceVolumeShakeEvent.Trigger(VolumeTween, FeedbackDuration, RemapVolumeZero, RemapVolumeOne, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cec28d1c770710c419ca4e4eaa9c79cd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control a camera's clipping planes over time. You'll need a MMCameraClippingPlanesShaker on your camera.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Camera/Clipping Planes")]
[FeedbackHelp("This feedback lets you control a camera's clipping planes over time. You'll need a MMCameraClippingPlanesShaker on your camera.")]
public class MMFeedbackCameraClippingPlanes : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.CameraColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Clipping Planes Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeClippingPlanes = false;
[Header("Near Plane")]
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeNear = 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 RemapNearZero = 0.3f;
/// the value to remap the curve's 1 to
[Tooltip("the value to remap the curve's 1 to")]
public float RemapNearOne = 100f;
[Header("Far Plane")]
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeFar = 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 RemapFarZero = 0.3f;
/// the value to remap the curve's 1 to
[Tooltip("the value to remap the curve's 1 to")]
public float RemapFarOne = 100f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
MMCameraClippingPlanesShakeEvent.Trigger(ShakeNear, FeedbackDuration, RemapNearZero, RemapNearOne,
ShakeFar, RemapFarZero, RemapFarOne,
RelativeClippingPlanes,
feedbacksIntensity, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMCameraClippingPlanesShakeEvent.Trigger(ShakeNear, FeedbackDuration, RemapNearZero, RemapNearOne,
ShakeFar, RemapFarZero, RemapFarOne, stop: true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 78a422fe88df96946ba8db179aea1389
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,86 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control a camera's field of view over time. You'll need a MMCameraFieldOfViewShaker on your camera.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Camera/Field of View")]
[FeedbackHelp("This feedback lets you control a camera's field of view over time. You'll need a MMCameraFieldOfViewShaker on your camera.")]
public class MMFeedbackCameraFieldOfView : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.CameraColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Field of View Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Field of View")]
/// 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;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMCameraFieldOfViewShakeEvent.Trigger(ShakeFieldOfView, FeedbackDuration, RemapFieldOfViewZero, RemapFieldOfViewOne, RelativeFieldOfView,
intensityMultiplier, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection, Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMCameraFieldOfViewShakeEvent.Trigger(ShakeFieldOfView, FeedbackDuration, RemapFieldOfViewZero, RemapFieldOfViewOne, stop: true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50b723ef43c645c42998408748e4170f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,84 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control a camera's orthographic size over time. You'll need a MMCameraOrthographicSizeShaker on your camera.
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Camera/Orthographic Size")]
[FeedbackHelp("This feedback lets you control a camera's orthographic size over time. You'll need a MMCameraOrthographicSizeShaker on your camera.")]
public class MMFeedbackCameraOrthographicSize : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.CameraColor; } }
#endif
/// returns the duration of the feedback
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
[Header("Orthographic Size Feedback")]
/// the channel to emit on
[Tooltip("the channel to emit on")]
public int Channel = 0;
/// the duration of the shake, in seconds
[Tooltip("the duration of the shake, in seconds")]
public float Duration = 2f;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
public bool ResetTargetValuesAfterShake = true;
[Header("Orthographic Size")]
/// whether or not to add to the initial value
[Tooltip("whether or not to add to the initial value")]
public bool RelativeOrthographicSize = false;
/// the curve used to animate the intensity value on
[Tooltip("the curve used to animate the intensity value on")]
public AnimationCurve ShakeOrthographicSize = 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 RemapOrthographicSizeZero = 5f;
/// the value to remap the curve's 1 to
[Tooltip("the value to remap the curve's 1 to")]
public float RemapOrthographicSizeOne = 10f;
/// <summary>
/// Triggers the corresponding coroutine
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
MMCameraOrthographicSizeShakeEvent.Trigger(ShakeOrthographicSize, FeedbackDuration, RemapOrthographicSizeZero, RemapOrthographicSizeOne, RelativeOrthographicSize,
feedbacksIntensity, ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake, NormalPlayDirection);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMCameraOrthographicSizeShakeEvent.Trigger(ShakeOrthographicSize, FeedbackDuration,
RemapOrthographicSizeZero, RemapOrthographicSizeOne, stop: true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 174b87f4e7a102a4ba0495310257cda6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will send a shake event when played
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("Define camera shake properties (duration in seconds, amplitude and frequency), and this will broadcast a MMCameraShakeEvent with these same settings. " +
"You'll need to add a MMCameraShaker on your camera for this to work (or a MMCinemachineCameraShaker component on your virtual camera if you're using Cinemachine). " +
"Note that although this event and system was built for cameras in mind, you could technically use it to shake other objects as well.")]
[FeedbackPath("Camera/Camera Shake")]
public class MMFeedbackCameraShake : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.CameraColor; } }
#endif
[Header("Camera Shake")]
/// whether or not this shake should repeat forever, until stopped
[Tooltip("whether or not this shake should repeat forever, until stopped")]
public bool RepeatUntilStopped = false;
/// the channel to broadcast this shake on
[Tooltip("the channel to broadcast this shake on")]
public int Channel = 0;
/// the properties of the shake (duration, intensity, frequenc)
[Tooltip("the properties of the shake (duration, intensity, frequenc)")]
public MMCameraShakeProperties CameraShakeProperties = new MMCameraShakeProperties(0.1f, 0.2f, 40f);
/// the duration of this feedback is the duration of the shake
public override float FeedbackDuration { get { return ApplyTimeMultiplier(CameraShakeProperties.Duration); } set { CameraShakeProperties.Duration = value; } }
/// <summary>
/// On Play, sends a shake camera event
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMCameraShakeEvent.Trigger(FeedbackDuration, CameraShakeProperties.Amplitude * intensityMultiplier, CameraShakeProperties.Frequency,
CameraShakeProperties.AmplitudeX * intensityMultiplier, CameraShakeProperties.AmplitudeY * intensityMultiplier, CameraShakeProperties.AmplitudeZ * intensityMultiplier,
RepeatUntilStopped, ChannelData(Channel), Timing.TimescaleMode == TimescaleModes.Unscaled);
}
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMCameraShakeStopEvent.Trigger(ChannelData(Channel));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d8fe7e41857f44348b52714b3238715c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// A feedback that will allow you to change the zoom of a (3D) camera when played
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("Define zoom properties : For will set the zoom to the specified parameters for a certain duration, " +
"Set will leave them like that forever. Zoom properties include the field of view, the duration of the " +
"zoom transition (in seconds) and the zoom duration (the time the camera should remain zoomed in, in seconds). " +
"For this to work, you'll need to add a MMCameraZoom component to your Camera, or a MMCinemachineZoom if you're " +
"using virtual cameras.")]
[FeedbackPath("Camera/Camera Zoom")]
public class MMFeedbackCameraZoom : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.CameraColor; } }
#endif
[Header("Camera Zoom")]
/// the channel to broadcast that zoom event on
[Tooltip("the channel to broadcast that zoom event on")]
public int Channel = 0;
/// the zoom mode (for : forward for TransitionDuration, static for Duration, backwards for TransitionDuration)
[Tooltip("the zoom mode (for : forward for TransitionDuration, static for Duration, backwards for TransitionDuration)")]
public MMCameraZoomModes ZoomMode = MMCameraZoomModes.For;
/// the target field of view
[Tooltip("the target field of view")]
public float ZoomFieldOfView = 30f;
/// the zoom transition duration
[Tooltip("the zoom transition duration")]
public float ZoomTransitionDuration = 0.05f;
/// the duration for which the zoom is at max zoom
[Tooltip("the duration for which the zoom is at max zoom")]
public float ZoomDuration = 0.1f;
/// whether or not ZoomFieldOfView should add itself to the current camera's field of view value
[Tooltip("whether or not ZoomFieldOfView should add itself to the current camera's field of view value")]
public bool RelativeFieldOfView = false;
/// the duration of this feedback is the duration of the zoom
public override float FeedbackDuration { get { return ApplyTimeMultiplier(ZoomDuration); } set { ZoomDuration = value; } }
/// <summary>
/// On Play, triggers a zoom event
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
MMCameraZoomEvent.Trigger(ZoomMode, ZoomFieldOfView, ZoomTransitionDuration, FeedbackDuration, ChannelData(Channel), Timing.TimescaleMode == TimescaleModes.Unscaled, false, RelativeFieldOfView);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMCameraZoomEvent.Trigger(ZoomMode, ZoomFieldOfView, ZoomTransitionDuration, FeedbackDuration, ChannelData(Channel), Timing.TimescaleMode == TimescaleModes.Unscaled, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 65811966b3e48ad4a9362cb8b1c4b83b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you turn the BlocksRaycast parameter of a target CanvasGroup on or off on play
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you turn the BlocksRaycast parameter of a target CanvasGroup on or off on play")]
[FeedbackPath("UI/CanvasGroup BlocksRaycasts")]
public class MMFeedbackCanvasGroupBlocksRaycasts : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.UIColor; } }
#endif
[Header("Canvas Group")]
/// the target canvas group we want to control the BlocksRaycasts parameter on
[Tooltip("the target canvas group we want to control the BlocksRaycasts parameter on")]
public CanvasGroup TargetCanvasGroup;
/// if this is true, on play, the target canvas group will block raycasts, if false it won't
[Tooltip("if this is true, on play, the target canvas group will block raycasts, if false it won't")]
public bool ShouldBlockRaycasts = true;
/// <summary>
/// On play we turn raycast block on or off
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (TargetCanvasGroup == null)
{
return;
}
TargetCanvasGroup.blocksRaycasts = ShouldBlockRaycasts;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 583ffcaa5dd1e9f46a29efb91fbf6a14
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you enable/disable/toggle a target collider, or change its trigger status
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you enable/disable/toggle a target collider, or change its trigger status")]
[FeedbackPath("GameObject/Collider")]
public class MMFeedbackCollider : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
/// the possible effects the feedback can have on the target collider's status
public enum Modes { Enable, Disable, ToggleActive, Trigger, NonTrigger, ToggleTrigger }
[Header("Collider")]
/// the collider to act upon
[Tooltip("the collider to act upon")]
public Collider TargetCollider;
/// the effect the feedback will have on the target collider's status
public Modes Mode = Modes.Disable;
/// <summary>
/// On Play we change the state of our collider if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (TargetCollider != null)
{
ApplyChanges(Mode);
}
}
/// <summary>
/// Changes the state of the collider
/// </summary>
/// <param name="state"></param>
protected virtual void ApplyChanges(Modes mode)
{
switch (mode)
{
case Modes.Enable:
TargetCollider.enabled = true;
break;
case Modes.Disable:
TargetCollider.enabled = false;
break;
case Modes.ToggleActive:
TargetCollider.enabled = !TargetCollider.enabled;
break;
case Modes.Trigger:
TargetCollider.isTrigger = true;
break;
case Modes.NonTrigger:
TargetCollider.isTrigger = false;
break;
case Modes.ToggleTrigger:
TargetCollider.isTrigger = !TargetCollider.isTrigger;
break;
default:
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2e86a09fcf977954587b031f4e7aa41e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you enable/disable/toggle a target collider 2D, or change its trigger status
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you enable/disable/toggle a target collider 2D, or change its trigger status")]
[FeedbackPath("GameObject/Collider2D")]
public class MMFeedbackCollider2D : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
/// the possible effects the feedback can have on the target collider's status
public enum Modes { Enable, Disable, ToggleActive, Trigger, NonTrigger, ToggleTrigger }
[Header("Collider")]
/// the collider to act upon
[Tooltip("the collider to act upon")]
public Collider2D TargetCollider2D;
/// the effect the feedback will have on the target collider's status
public Modes Mode = Modes.Disable;
/// <summary>
/// On Play we change the state of our collider if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetCollider2D == null))
{
return;
}
ApplyChanges(Mode);
}
/// <summary>
/// Changes the state of the collider
/// </summary>
/// <param name="state"></param>
protected virtual void ApplyChanges(Modes mode)
{
switch (mode)
{
case Modes.Enable:
TargetCollider2D.enabled = true;
break;
case Modes.Disable:
TargetCollider2D.enabled = false;
break;
case Modes.ToggleActive:
TargetCollider2D.enabled = !TargetCollider2D.enabled;
break;
case Modes.Trigger:
TargetCollider2D.isTrigger = true;
break;
case Modes.NonTrigger:
TargetCollider2D.isTrigger = false;
break;
case Modes.ToggleTrigger:
TargetCollider2D.isTrigger = !TargetCollider2D.isTrigger;
break;
default:
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5392495cf1075b44cb26df302c9c6d8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,242 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you animate the position/rotation/scale of a target transform to match the one of a destination transform.
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you animate the position/rotation/scale of a target transform to match the one of a destination transform.")]
[FeedbackPath("Transform/Destination")]
public class MMFeedbackDestinationTransform : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the possible timescales this feedback can animate on
public enum TimeScales { Scaled, Unscaled }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.TransformColor; } }
#endif
[Header("Target to animate")]
/// the target transform we want to animate properties on
[Tooltip("the target transform we want to animate properties on")]
public Transform TargetTransform;
[Header("Origin and destination")]
/// whether or not we want to force an origin transform. If not, the current position of the target transform will be used as origin instead
[Tooltip("whether or not we want to force an origin transform. If not, the current position of the target transform will be used as origin instead")]
public bool ForceOrigin = false;
/// the transform to use as origin in ForceOrigin mode
[Tooltip("the transform to use as origin in ForceOrigin mode")]
[MMFCondition("ForceOrigin", true)]
public Transform Origin;
/// the destination transform whose properties we want to match
[Tooltip("the destination transform whose properties we want to match")]
public Transform Destination;
[Header("Transition")]
/// the timescale to animate on
[Tooltip("the timescale to animate on")]
public TimeScales TimeScale = TimeScales.Scaled;
/// whether or not we want to force transform properties at the end of the transition
[Tooltip("whether or not we want to force transform properties at the end of the transition")]
public bool ForceDestinationOnEnd = false;
/// a global curve to animate all properties on, unless dedicated ones are specified
[Tooltip("a global curve to animate all properties on, unless dedicated ones are specified")]
public AnimationCurve GlobalAnimationCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// the duration of the transition, in seconds
[Tooltip("the duration of the transition, in seconds")]
public float Duration = 0.2f;
[Header("Axis Locks")]
/// whether or not to animate the X position
[Tooltip("whether or not to animate the X Position")]
public bool AnimatePositionX = true;
/// whether or not to animate the Y position
[Tooltip("whether or not to animate the Y Position")]
public bool AnimatePositionY = true;
/// whether or not to animate the Z position
[Tooltip("whether or not to animate the Z Position")]
public bool AnimatePositionZ = true;
/// whether or not to animate the X rotation
[Tooltip("whether or not to animate the X rotation")]
public bool AnimateRotationX = true;
/// whether or not to animate the Y rotation
[Tooltip("whether or not to animate the Y rotation")]
public bool AnimateRotationY = true;
/// whether or not to animate the Z rotation
[Tooltip("whether or not to animate the Z rotation")]
public bool AnimateRotationZ = true;
/// whether or not to animate the W rotation
[Tooltip("whether or not to animate the W rotation")]
public bool AnimateRotationW = true;
/// whether or not to animate the X scale
[Tooltip("whether or not to animate the X scale")]
public bool AnimateScaleX = true;
/// whether or not to animate the Y scale
[Tooltip("whether or not to animate the Y scale")]
public bool AnimateScaleY = true;
/// whether or not to animate the Z scale
[Tooltip("whether or not to animate the Z scale")]
public bool AnimateScaleZ = true;
[Header("Separate Curves")]
/// whether or not to use a separate animation curve to animate the position
[Tooltip("whether or not to use a separate animation curve to animate the position")]
public bool SeparatePositionCurve = false;
/// the curve to use to animate the position on
[Tooltip("the curve to use to animate the position on")]
[MMFCondition("SeparatePositionCurve", true)]
public AnimationCurve AnimatePositionCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// whether or not to use a separate animation curve to animate the rotation
[Tooltip("whether or not to use a separate animation curve to animate the rotation")]
public bool SeparateRotationCurve = false;
/// the curve to use to animate the rotation on
[Tooltip("the curve to use to animate the rotation on")]
[MMFCondition("SeparateRotationCurve", true)]
public AnimationCurve AnimateRotationCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// whether or not to use a separate animation curve to animate the scale
[Tooltip("whether or not to use a separate animation curve to animate the scale")]
public bool SeparateScaleCurve = false;
/// the curve to use to animate the scale on
[Tooltip("the curve to use to animate the scale on")]
[MMFCondition("SeparateScaleCurve", true)]
public AnimationCurve AnimateScaleCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// the duration of this feedback is the duration of the movement
public override float FeedbackDuration { get { return ApplyTimeMultiplier(Duration); } set { Duration = value; } }
protected Coroutine _coroutine;
protected Vector3 _newPosition;
protected Quaternion _newRotation;
protected Vector3 _newScale;
protected Vector3 _pointAPosition;
protected Vector3 _pointBPosition;
protected Quaternion _pointARotation;
protected Quaternion _pointBRotation;
protected Vector3 _pointAScale;
protected Vector3 _pointBScale;
protected AnimationCurve _animationCurve;
/// <summary>
/// On Play we animate the pos/rotation/scale of the target transform towards its destination
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetTransform == null))
{
return;
}
_coroutine = StartCoroutine(AnimateToDestination());
}
/// <summary>
/// A coroutine used to animate the pos/rotation/scale of the target transform towards its destination
/// </summary>
/// <returns></returns>
protected virtual IEnumerator AnimateToDestination()
{
_pointAPosition = ForceOrigin ? Origin.transform.position : TargetTransform.position;
_pointBPosition = Destination.transform.position;
if (!AnimatePositionX) { _pointAPosition.x = TargetTransform.position.x; _pointBPosition.x = _pointAPosition.x; }
if (!AnimatePositionY) { _pointAPosition.y = TargetTransform.position.y; _pointBPosition.y = _pointAPosition.y; }
if (!AnimatePositionZ) { _pointAPosition.z = TargetTransform.position.z; _pointBPosition.z = _pointAPosition.z; }
_pointARotation = ForceOrigin ? Origin.transform.rotation : TargetTransform.rotation;
_pointBRotation = Destination.transform.rotation;
if (!AnimateRotationX) { _pointARotation.x = TargetTransform.rotation.x; _pointBRotation.x = _pointARotation.x; }
if (!AnimateRotationY) { _pointARotation.y = TargetTransform.rotation.y; _pointBRotation.y = _pointARotation.y; }
if (!AnimateRotationZ) { _pointARotation.z = TargetTransform.rotation.z; _pointBRotation.z = _pointARotation.z; }
if (!AnimateRotationW) { _pointARotation.w = TargetTransform.rotation.w; _pointBRotation.w = _pointARotation.w; }
_pointAScale = ForceOrigin ? Origin.transform.localScale : TargetTransform.localScale;
_pointBScale = Destination.transform.localScale;
if (!AnimateScaleX) { _pointAScale.x = TargetTransform.localScale.x; _pointBScale.x = _pointAScale.x; }
if (!AnimateScaleY) { _pointAScale.y = TargetTransform.localScale.y; _pointBScale.y = _pointAScale.y; }
if (!AnimateScaleZ) { _pointAScale.z = TargetTransform.localScale.z; _pointBScale.z = _pointAScale.z; }
IsPlaying = true;
float journey = NormalPlayDirection ? 0f : Duration;
while ((journey >= 0) && (journey <= Duration) && (Duration > 0))
{
float percent = Mathf.Clamp01(journey / Duration);
_animationCurve = SeparatePositionCurve ? AnimatePositionCurve : GlobalAnimationCurve;
_newPosition = Vector3.LerpUnclamped(_pointAPosition, _pointBPosition, _animationCurve.Evaluate(percent));
_animationCurve = SeparateRotationCurve ? AnimateRotationCurve : GlobalAnimationCurve;
_newRotation = Quaternion.LerpUnclamped(_pointARotation, _pointBRotation, _animationCurve.Evaluate(percent));
_animationCurve = SeparateScaleCurve ? AnimateScaleCurve : GlobalAnimationCurve;
_newScale = Vector3.LerpUnclamped(_pointAScale, _pointBScale, _animationCurve.Evaluate(percent));
TargetTransform.position = _newPosition;
TargetTransform.rotation = _newRotation;
TargetTransform.localScale = _newScale;
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
// set final position
if (ForceDestinationOnEnd)
{
if (NormalPlayDirection)
{
TargetTransform.position = _pointBPosition;
TargetTransform.rotation = _pointBRotation;
TargetTransform.localScale = _pointBScale;
}
else
{
TargetTransform.position = _pointAPosition;
TargetTransform.rotation = _pointARotation;
TargetTransform.localScale = _pointAScale;
}
}
IsPlaying = false;
_coroutine = null;
yield break;
}
/// <summary>
/// On Stop we stop our coroutine if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
IsPlaying = false;
if ((TargetTransform != null) && (_coroutine != null))
{
StopCoroutine(_coroutine);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e4a4e5090b88934280a43db1221457d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,67 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback allows you to destroy a target gameobject, either via Destroy, DestroyImmediate, or SetActive:False
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to destroy a target gameobject, either via Destroy, DestroyImmediate, or SetActive:False")]
[FeedbackPath("GameObject/Destroy")]
public class MMFeedbackDestroy : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
/// the possible ways to destroy an object
public enum Modes { Destroy, DestroyImmediate, Disable }
[Header("Destroy")]
/// the gameobject we want to change the active state of
[Tooltip("the gameobject we want to change the active state of")]
public GameObject TargetGameObject;
/// the selected destruction mode
[Tooltip("the selected destruction mode")]
public Modes Mode;
/// <summary>
/// On Play we change the state of our Behaviour if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetGameObject == null))
{
return;
}
ProceedWithDestruction(TargetGameObject);
}
/// <summary>
/// Changes the status of the Behaviour
/// </summary>
/// <param name="state"></param>
protected virtual void ProceedWithDestruction(GameObject go)
{
switch (Mode)
{
case Modes.Destroy:
Destroy(go);
break;
case Modes.DestroyImmediate:
DestroyImmediate(go);
break;
case Modes.Disable:
go.SetActive(false);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a735df4ed5161bc4a89ba41ab2149469
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,155 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// Turns an object active or inactive at the various stages of the feedback
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to change the state of a behaviour on a target gameobject from active to inactive (or the opposite), on init, play, stop or reset. " +
"For each of these you can specify if you want to force a state (enabled or disabled), or toggle it (enabled becomes disabled, disabled becomes enabled).")]
[FeedbackPath("GameObject/Enable Behaviour")]
public class MMFeedbackEnable : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
/// the possible effects the feedback can have on the target object's status
public enum PossibleStates { Enabled, Disabled, Toggle }
[Header("Set Active")]
/// the gameobject we want to change the active state of
[Tooltip("the gameobject we want to change the active state of")]
public Behaviour TargetBehaviour;
/// whether or not we should alter the state of the target object on init
[Tooltip("whether or not we should alter the state of the target object on init")]
public bool SetStateOnInit = false;
/// how to change the state on init
[MMFCondition("SetStateOnInit", true)]
[Tooltip("how to change the state on init")]
public PossibleStates StateOnInit = PossibleStates.Disabled;
/// whether or not we should alter the state of the target object on play
[Tooltip("whether or not we should alter the state of the target object on play")]
public bool SetStateOnPlay = false;
/// how to change the state on play
[MMFCondition("SetStateOnPlay", true)]
[Tooltip("how to change the state on play")]
public PossibleStates StateOnPlay = PossibleStates.Disabled;
/// whether or not we should alter the state of the target object on stop
[Tooltip("whether or not we should alter the state of the target object on stop")]
public bool SetStateOnStop = false;
/// how to change the state on stop
[Tooltip("how to change the state on stop")]
[MMFCondition("SetStateOnStop", true)]
public PossibleStates StateOnStop = PossibleStates.Disabled;
/// whether or not we should alter the state of the target object on reset
[Tooltip("whether or not we should alter the state of the target object on reset")]
public bool SetStateOnReset = false;
/// how to change the state on reset
[Tooltip("how to change the state on reset")]
[MMFCondition("SetStateOnReset", true)]
public PossibleStates StateOnReset = PossibleStates.Disabled;
/// <summary>
/// On init we change the state of our Behaviour if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && (TargetBehaviour != null))
{
if (SetStateOnInit)
{
SetStatus(StateOnInit);
}
}
}
/// <summary>
/// On Play we change the state of our Behaviour if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetBehaviour == null))
{
return;
}
if (SetStateOnPlay)
{
SetStatus(StateOnPlay);
}
}
/// <summary>
/// On Stop we change the state of our Behaviour if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized || (TargetBehaviour == null))
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
if (SetStateOnStop)
{
SetStatus(StateOnStop);
}
}
/// <summary>
/// On Reset we change the state of our Behaviour if needed
/// </summary>
protected override void CustomReset()
{
base.CustomReset();
if (InCooldown)
{
return;
}
if (!Active || !FeedbackTypeAuthorized || (TargetBehaviour == null))
{
return;
}
if (SetStateOnReset)
{
SetStatus(StateOnReset);
}
}
/// <summary>
/// Changes the status of the Behaviour
/// </summary>
/// <param name="state"></param>
protected virtual void SetStatus(PossibleStates state)
{
switch (state)
{
case PossibleStates.Enabled:
TargetBehaviour.enabled = NormalPlayDirection ? true : false;
break;
case PossibleStates.Disabled:
TargetBehaviour.enabled = NormalPlayDirection ? false : true;
break;
case PossibleStates.Toggle:
TargetBehaviour.enabled = !TargetBehaviour.enabled;
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d32bf9d337140142b62c61d26aff604
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,91 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// A feedback to bind Unity events to and trigger them when played
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to bind any type of Unity events to this feebdack's Play, Stop, Initialization and Reset methods.")]
[FeedbackPath("Events/Events")]
public class MMFeedbackEvents : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.EventsColor; } }
#endif
[Header("Events")]
/// the events to trigger when the feedback is played
[Tooltip("the events to trigger when the feedback is played")]
public UnityEvent PlayEvents;
/// the events to trigger when the feedback is stopped
[Tooltip("the events to trigger when the feedback is stopped")]
public UnityEvent StopEvents;
/// the events to trigger when the feedback is initialized
[Tooltip("the events to trigger when the feedback is initialized")]
public UnityEvent InitializationEvents;
/// the events to trigger when the feedback is reset
[Tooltip("the events to trigger when the feedback is reset")]
public UnityEvent ResetEvents;
/// <summary>
/// On init, triggers the init events
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && (InitializationEvents != null))
{
InitializationEvents.Invoke();
}
}
/// <summary>
/// On Play, triggers the play events
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (PlayEvents == null))
{
return;
}
PlayEvents.Invoke();
}
/// <summary>
/// On Stop, triggers the stop events
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (StopEvents == null))
{
return;
}
StopEvents.Invoke();
}
/// <summary>
/// On reset, triggers the reset events
/// </summary>
protected override void CustomReset()
{
if (!Active || !FeedbackTypeAuthorized || (ResetEvents == null))
{
return;
}
base.CustomReset();
ResetEvents.Invoke();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 23a102c1a91e34644aa37f1e4f00c31a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// Turns an object active or inactive at the various stages of the feedback
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to trigger any MMFeedbacks on the specified Channel within a certain range. You'll need an MMFeedbacksShaker on them.")]
[FeedbackPath("GameObject/MMFeedbacks")]
public class MMFeedbackFeedbacks : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the duration of this feedback is 0
public override float FeedbackDuration { get { return 0f; } }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
[Header("MMFeedbacks")]
/// the channel to broadcast on
[Tooltip("the channel to broadcast on")]
public int Channel = 0;
/// whether or not to use a range
[Tooltip("whether or not to use a range")]
public bool UseRange = false;
/// the range of the event, in units
[Tooltip("the range of the event, in units")]
public float EventRange = 100f;
/// the transform to use to broadcast the event as origin point
[Tooltip("the transform to use to broadcast the event as origin point")]
public Transform EventOriginTransform;
/// <summary>
/// On init we turn the light off if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (EventOriginTransform == null)
{
EventOriginTransform = this.transform;
}
}
/// <summary>
/// On Play we trigger our feedback shake event
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
MMFeedbacksShakeEvent.Trigger(ChannelData(Channel), UseRange, EventRange, EventOriginTransform.position);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 31d37db53bc279e41b823421b7ef20bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,73 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will trigger a flash event (to be caught by a MMFlash) when played
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("On play, this feedback will broadcast a MMFlashEvent. If you create a UI image with a MMFlash component on it (see example in the Demo scene), it will intercept that event, and flash (usually you'll want it to take the full size of your screen, but that's not mandatory). In the feedback's inspector, you can define the color of the flash, its duration, alpha, and a FlashID. That FlashID needs to be the same on your feedback and MMFlash for them to work together. This allows you to have multiple MMFlashs in your scene, and flash them separately.")]
[FeedbackPath("Camera/Flash")]
public class MMFeedbackFlash : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.CameraColor; } }
#endif
[Header("Flash")]
/// the channel to broadcast that flash event on
[Tooltip("the channel to broadcast that flash event on")]
public int Channel = 0;
/// the color of the flash
[Tooltip("the color of the flash")]
public Color FlashColor = Color.white;
/// the flash duration (in seconds)
[Tooltip("the flash duration (in seconds)")]
public float FlashDuration = 0.2f;
/// the alpha of the flash
[Tooltip("the alpha of the flash")]
public float FlashAlpha = 1f;
/// the ID of the flash (usually 0). You can specify on each MMFlash object an ID, allowing you to have different flash images in one scene and call them separately (one for damage, one for health pickups, etc)
[Tooltip("the ID of the flash (usually 0). You can specify on each MMFlash object an ID, allowing you to have different flash images in one scene and call them separately (one for damage, one for health pickups, etc)")]
public int FlashID = 0;
/// the duration of this feedback is the duration of the flash
public override float FeedbackDuration { get { return ApplyTimeMultiplier(FlashDuration); } set { FlashDuration = value; } }
/// <summary>
/// On Play we trigger a flash event
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
MMFlashEvent.Trigger(FlashColor, FeedbackDuration * intensityMultiplier, FlashAlpha, FlashID, ChannelData(Channel), Timing.TimescaleMode);
}
/// <summary>
/// On stop we stop our transition
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
MMFlashEvent.Trigger(FlashColor, FeedbackDuration, FlashAlpha, FlashID, ChannelData(Channel), Timing.TimescaleMode, stop:true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4cf8e1825623fb34b9fc92dbef54ec56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,282 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will make the bound renderer flicker for the set duration when played (and restore its initial color when stopped)
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback lets you flicker the color of a specified renderer (sprite, mesh, etc) for a certain duration, at the specified octave, and with the specified color. Useful when a character gets hit, for example (but so much more!).")]
[FeedbackPath("Renderer/Flicker")]
public class MMFeedbackFlicker : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.RendererColor; } }
#endif
/// the possible modes
/// Color : will control material.color
/// PropertyName : will target a specific shader property by name
public enum Modes { Color, PropertyName }
[Header("Flicker")]
/// the renderer to flicker when played
[Tooltip("the renderer to flicker when played")]
public Renderer BoundRenderer;
/// the selected mode to flicker the renderer
[Tooltip("the selected mode to flicker the renderer")]
public Modes Mode = Modes.Color;
/// the name of the property to target
[MMFEnumCondition("Mode", (int)Modes.PropertyName)]
[Tooltip("the name of the property to target")]
public string PropertyName = "_Tint";
/// the duration of the flicker when getting damage
[Tooltip("the duration of the flicker when getting damage")]
public float FlickerDuration = 0.2f;
/// the duration of the period for the flicker
[Tooltip("the duration of the period for the flicker")]
[FormerlySerializedAs("FlickerOctave")]
public float FlickerPeriod = 0.04f;
/// the color we should flicker the sprite to
[Tooltip("the color we should flicker the sprite to")]
[ColorUsage(true, true)]
public Color FlickerColor = new Color32(255, 20, 20, 255);
/// the list of material indexes we want to flicker on the target renderer. If left empty, will only target the material at index 0
[Tooltip("the list of material indexes we want to flicker on the target renderer. If left empty, will only target the material at index 0")]
public int[] MaterialIndexes;
/// if this is true, this component will use material property blocks instead of working on an instance of the material.
[Tooltip("if this is true, this component will use material property blocks instead of working on an instance of the material.")]
public bool UseMaterialPropertyBlocks = false;
/// the duration of this feedback is the duration of the flicker
public override float FeedbackDuration { get { return ApplyTimeMultiplier(FlickerDuration); } set { FlickerDuration = value; } }
protected const string _colorPropertyName = "_Color";
protected Color[] _initialFlickerColors;
protected int[] _propertyIDs;
protected bool[] _propertiesFound;
protected Coroutine[] _coroutines;
protected MaterialPropertyBlock _propertyBlock;
/// <summary>
/// On init we grab our initial color and components
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
if (MaterialIndexes.Length == 0)
{
MaterialIndexes = new int[1];
MaterialIndexes[0] = 0;
}
_coroutines = new Coroutine[MaterialIndexes.Length];
_initialFlickerColors = new Color[MaterialIndexes.Length];
_propertyIDs = new int[MaterialIndexes.Length];
_propertiesFound = new bool[MaterialIndexes.Length];
_propertyBlock = new MaterialPropertyBlock();
if (Active && (BoundRenderer == null) && (owner != null))
{
if (owner.MMFGetComponentNoAlloc<Renderer>() != null)
{
BoundRenderer = owner.GetComponent<Renderer>();
}
if (BoundRenderer == null)
{
BoundRenderer = owner.GetComponentInChildren<Renderer>();
}
}
if (BoundRenderer == null)
{
Debug.LogWarning("[MMFeedbackFlicker] The flicker feedback on "+this.name+" doesn't have a bound renderer, it won't work. You need to specify a renderer to flicker in its inspector.");
}
if (Active)
{
if (BoundRenderer != null)
{
BoundRenderer.GetPropertyBlock(_propertyBlock);
}
}
for (int i = 0; i < MaterialIndexes.Length; i++)
{
_propertiesFound[i] = false;
if (Active && (BoundRenderer != null))
{
if (Mode == Modes.Color)
{
_propertiesFound[i] = UseMaterialPropertyBlocks ? BoundRenderer.sharedMaterials[i].HasProperty(_colorPropertyName) : BoundRenderer.materials[i].HasProperty(_colorPropertyName);
if (_propertiesFound[i])
{
_initialFlickerColors[i] = UseMaterialPropertyBlocks ? BoundRenderer.sharedMaterials[i].color : BoundRenderer.materials[i].color;
}
}
else
{
_propertiesFound[i] = UseMaterialPropertyBlocks ? BoundRenderer.sharedMaterials[i].HasProperty(PropertyName) : BoundRenderer.materials[i].HasProperty(PropertyName);
if (_propertiesFound[i])
{
_propertyIDs[i] = Shader.PropertyToID(PropertyName);
_initialFlickerColors[i] = UseMaterialPropertyBlocks ? BoundRenderer.sharedMaterials[i].GetColor(_propertyIDs[i]) : BoundRenderer.materials[i].GetColor(_propertyIDs[i]);
}
}
}
}
}
/// <summary>
/// On play we make our renderer flicker
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (BoundRenderer == null))
{
return;
}
for (int i = 0; i < MaterialIndexes.Length; i++)
{
_coroutines[i] = StartCoroutine(Flicker(BoundRenderer, i, _initialFlickerColors[i], FlickerColor, FlickerPeriod, FeedbackDuration));
}
}
/// <summary>
/// On reset we make our renderer stop flickering
/// </summary>
protected override void CustomReset()
{
base.CustomReset();
if (InCooldown)
{
return;
}
if (Active && FeedbackTypeAuthorized && (BoundRenderer != null))
{
for (int i = 0; i < MaterialIndexes.Length; i++)
{
SetColor(i, _initialFlickerColors[i]);
}
}
}
public virtual IEnumerator Flicker(Renderer renderer, int materialIndex, Color initialColor, Color flickerColor, float flickerSpeed, float flickerDuration)
{
if (renderer == null)
{
yield break;
}
if (!_propertiesFound[materialIndex])
{
yield break;
}
if (initialColor == flickerColor)
{
yield break;
}
float flickerStop = FeedbackTime + flickerDuration;
IsPlaying = true;
while (FeedbackTime < flickerStop)
{
SetColor(materialIndex, flickerColor);
if (Timing.TimescaleMode == TimescaleModes.Scaled)
{
yield return MMFeedbacksCoroutine.WaitFor(flickerSpeed);
}
else
{
yield return MMFeedbacksCoroutine.WaitForUnscaled(flickerSpeed);
}
SetColor(materialIndex, initialColor);
if (Timing.TimescaleMode == TimescaleModes.Scaled)
{
yield return MMFeedbacksCoroutine.WaitFor(flickerSpeed);
}
else
{
yield return MMFeedbacksCoroutine.WaitForUnscaled(flickerSpeed);
}
}
SetColor(materialIndex, initialColor);
IsPlaying = false;
}
protected virtual void SetColor(int materialIndex, Color color)
{
if (!_propertiesFound[materialIndex])
{
return;
}
if (Mode == Modes.Color)
{
if (UseMaterialPropertyBlocks)
{
BoundRenderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor(_colorPropertyName, color);
BoundRenderer.SetPropertyBlock(_propertyBlock, materialIndex);
}
else
{
BoundRenderer.materials[materialIndex].color = color;
}
}
else
{
if (UseMaterialPropertyBlocks)
{
BoundRenderer.GetPropertyBlock(_propertyBlock);
_propertyBlock.SetColor(_propertyIDs[materialIndex], color);
BoundRenderer.SetPropertyBlock(_propertyBlock, materialIndex);
}
else
{
BoundRenderer.materials[materialIndex].SetColor(_propertyIDs[materialIndex], color);
}
}
}
/// <summary>
/// Stops this feedback
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
IsPlaying = false;
for (int i = 0; i < _coroutines.Length; i++)
{
if (_coroutines[i] != null)
{
StopCoroutine(_coroutines[i]);
}
_coroutines[i] = null;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d83ae645c92af634f89036dd5302f84a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will trigger a freeze frame event when played, pausing the game for the specified duration (usually short, but not necessarily)
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will freeze the timescale for the specified duration (in seconds). I usually go with 0.01s or 0.02s, but feel free to tweak it to your liking. It requires a MMTimeManager in your scene to work.")]
[FeedbackPath("Time/Freeze Frame")]
public class MMFeedbackFreezeFrame : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.TimeColor; } }
#endif
[Header("Freeze Frame")]
/// the duration of the freeze frame
[Tooltip("the duration of the freeze frame")]
public float FreezeFrameDuration = 0.02f;
/// the minimum value the timescale should be at for this freeze frame to happen. This can be useful to avoid triggering freeze frames when the timescale is already frozen.
[Tooltip("the minimum value the timescale should be at for this freeze frame to happen. This can be useful to avoid triggering freeze frames when the timescale is already frozen.")]
public float MinimumTimescaleThreshold = 0.1f;
/// the duration of this feedback is the duration of the freeze frame
public override float FeedbackDuration { get { return ApplyTimeMultiplier(FreezeFrameDuration); } set { FreezeFrameDuration = value; } }
/// <summary>
/// On Play we trigger a freeze frame event
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (Time.timeScale < MinimumTimescaleThreshold)
{
return;
}
MMFreezeFrameEvent.Trigger(FeedbackDuration);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86fec89a17b5b2347a82ae1c77aced3d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// this feedback will "hold", or wait, until all previous feedbacks have been executed, and will then pause the execution of your MMFeedbacks sequence, for the specified duration
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will 'hold', or wait, until all previous feedbacks have been executed, and will then pause the execution of your MMFeedbacks sequence, for the specified duration.")]
[FeedbackPath("Pause/Holding Pause")]
public class MMFeedbackHoldingPause : MMFeedbackPause
{
/// sets the color of this feedback in the inspector
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.HoldingPauseColor; } }
#endif
public override bool HoldingPause { get { return true; } }
/// the duration of this feedback is the duration of the pause
public override float FeedbackDuration { get { return ApplyTimeMultiplier(PauseDuration); } set { PauseDuration = value; } }
/// <summary>
/// On custom play we just play our pause
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
StartCoroutine(PlayPause());
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f1480e377932bb4cab1ab6851bbdbf3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,219 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you change the color of a target sprite renderer over time, and flip it on X or Y. You can also use it to command one or many MMSpriteRendererShakers.
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you change the color of a target Image over time. You can also use it to command one or many MMImageShakers.")]
[FeedbackPath("UI/Image")]
public class MMFeedbackImage : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.UIColor; } }
#endif
/// the possible modes for this feedback
public enum Modes { OverTime, Instant, ShakerEvent }
[Header("Sprite Renderer")]
/// the Image to affect when playing the feedback
[Tooltip("the Image to affect when playing the feedback")]
public Image BoundImage;
/// whether the feedback should affect the Image instantly or over a period of time
[Tooltip("whether the feedback should affect the Image instantly or over a period of time")]
public Modes Mode = Modes.OverTime;
/// how long the Image should change over time
[Tooltip("how long the Image should change over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float Duration = 0.2f;
/// whether or not that Image should be turned off on start
[Tooltip("whether or not that Image should be turned off on start")]
public bool StartsOff = false;
/// the channel to broadcast on
[Tooltip("the channel to broadcast on")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public int Channel = 0;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool ResetTargetValuesAfterShake = true;
/// whether or not to broadcast a range to only affect certain shakers
[Tooltip("whether or not to broadcast a range to only affect certain shakers")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool UseRange = false;
/// the range of the event, in units
[Tooltip("the range of the event, in units")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public float EventRange = 100f;
/// the transform to use to broadcast the event as origin point
[Tooltip("the transform to use to broadcast the event as origin point")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public Transform EventOriginTransform;
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
/// if this is true, the target will be disabled when this feedbacks is stopped
[Tooltip("if this is true, the target will be disabled when this feedbacks is stopped")]
public bool DisableOnStop = true;
[Header("Color")]
/// whether or not to modify the color of the image
[Tooltip("whether or not to modify the color of the image")]
public bool ModifyColor = true;
/// the colors to apply to the Image over time
[Tooltip("the colors to apply to the Image over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public Gradient ColorOverTime;
/// the color to move to in instant mode
[Tooltip("the color to move to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant, (int)Modes.ShakerEvent)]
public Color InstantColor;
/// the duration of this feedback is the duration of the Image, or 0 if instant
public override float FeedbackDuration { get { return (Mode == Modes.Instant) ? 0f : ApplyTimeMultiplier(Duration); } set { Duration = value; } }
protected Coroutine _coroutine;
/// <summary>
/// On init we turn the Image off if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (EventOriginTransform == null)
{
EventOriginTransform = this.transform;
}
if (Active)
{
if (StartsOff)
{
Turn(false);
}
}
}
/// <summary>
/// On Play we turn our Image on and start an over time coroutine if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
Turn(true);
switch (Mode)
{
case Modes.Instant:
if (ModifyColor)
{
BoundImage.color = InstantColor;
}
break;
case Modes.OverTime:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(ImageSequence());
break;
case Modes.ShakerEvent:
/*MMImageShakeEvent.Trigger(Duration, ModifyColor, ColorOverTime,
feedbacksIntensity,
Channel, ResetShakerValuesAfterShake, ResetTargetValuesAfterShake,
UseRange, EventRange, EventOriginTransform.position);*/
break;
}
}
/// <summary>
/// This coroutine will modify the values on the Image
/// </summary>
/// <returns></returns>
protected virtual IEnumerator ImageSequence()
{
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
IsPlaying = true;
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float remappedTime = MMFeedbacksHelpers.Remap(journey, 0f, FeedbackDuration, 0f, 1f);
SetImageValues(remappedTime);
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
yield return null;
}
SetImageValues(FinalNormalizedTime);
if (StartsOff)
{
Turn(false);
}
IsPlaying = false;
_coroutine = null;
yield return null;
}
/// <summary>
/// Sets the various values on the sprite renderer on a specified time (between 0 and 1)
/// </summary>
/// <param name="time"></param>
protected virtual void SetImageValues(float time)
{
if (ModifyColor)
{
BoundImage.color = ColorOverTime.Evaluate(time);
}
}
/// <summary>
/// Turns the sprite renderer off on stop
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
IsPlaying = false;
base.CustomStopFeedback(position, feedbacksIntensity);
if (Active && DisableOnStop)
{
Turn(false);
}
_coroutine = null;
}
/// <summary>
/// Turns the sprite renderer on or off
/// </summary>
/// <param name="status"></param>
protected virtual void Turn(bool status)
{
BoundImage.gameObject.SetActive(status);
BoundImage.enabled = status;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb334e9c7508c274bbc3b4ed998d49cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
using System.Collections;
using System.Collections.Generic;
using System.Net.Mime;
using UnityEngine;
using UnityEngine.UI;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you control the RaycastTarget parameter of a target image, turning it on or off on play
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you control the RaycastTarget parameter of a target image, turning it on or off on play")]
[FeedbackPath("UI/Image RaycastTarget")]
public class MMFeedbackImageRaycastTarget : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.UIColor; } }
#endif
[Header("Image")]
/// the target Image we want to control the RaycastTarget parameter on
[Tooltip("the target Image we want to control the RaycastTarget parameter on")]
public Image TargetImage;
/// if this is true, when played, the target image will become a raycast target
[Tooltip("if this is true, when played, the target image will become a raycast target")]
public bool ShouldBeRaycastTarget = true;
/// <summary>
/// On play we turn raycastTarget on or off
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (TargetImage == null)
{
return;
}
TargetImage.raycastTarget = NormalPlayDirection ? ShouldBeRaycastTarget : !ShouldBeRaycastTarget;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67f5c077bcc97b14abafb6cde2181dac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,221 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will instantiate the associated object (usually a VFX, but not necessarily), optionnally creating an object pool of them for performance
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to instantiate the object specified in its inspector, at the feedback's position (plus an optional offset). You can also optionally (and automatically) create an object pool at initialization to save on performance. In that case you'll need to specify a pool size (usually the maximum amount of these instantiated objects you plan on having in your scene at each given time).")]
[FeedbackPath("GameObject/Instantiate Object")]
public class MMFeedbackInstantiateObject : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the different ways to position the instantiated object :
/// - FeedbackPosition : object will be instantiated at the position of the feedback, plus an optional offset
/// - Transform : the object will be instantiated at the specified Transform's position, plus an optional offset
/// - WorldPosition : the object will be instantiated at the specified world position vector, plus an optional offset
/// - Script : the position passed in parameters when calling the feedback
public enum PositionModes { FeedbackPosition, Transform, WorldPosition, Script }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
[Header("Instantiate Object")]
/// the object to instantiate
[Tooltip("the object to instantiate")]
[FormerlySerializedAs("VfxToInstantiate")]
public GameObject GameObjectToInstantiate;
[Header("Position")]
/// the chosen way to position the object
[Tooltip("the chosen way to position the object")]
public PositionModes PositionMode = PositionModes.FeedbackPosition;
/// the chosen way to position the object
[Tooltip("the chosen way to position the object")]
public bool AlsoApplyRotation = false;
/// the chosen way to position the object
[Tooltip("the chosen way to position the object")]
public bool AlsoApplyScale = false;
/// the transform at which to instantiate the object
[Tooltip("the transform at which to instantiate the object")]
[MMFEnumCondition("PositionMode", (int)PositionModes.Transform)]
public Transform TargetTransform;
/// the transform at which to instantiate the object
[Tooltip("the transform at which to instantiate the object")]
[MMFEnumCondition("PositionMode", (int)PositionModes.WorldPosition)]
public Vector3 TargetPosition;
/// the position offset at which to instantiate the object
[Tooltip("the position offset at which to instantiate the object")]
[FormerlySerializedAs("VfxPositionOffset")]
public Vector3 PositionOffset;
[Header("Object Pool")]
/// whether or not we should create automatically an object pool for this object
[Tooltip("whether or not we should create automatically an object pool for this object")]
[FormerlySerializedAs("VfxCreateObjectPool")]
public bool CreateObjectPool;
/// the initial and planned size of this object pool
[Tooltip("the initial and planned size of this object pool")]
[MMFCondition("CreateObjectPool", true)]
[FormerlySerializedAs("VfxObjectPoolSize")]
public int ObjectPoolSize = 5;
/// whether or not to create a new pool even if one already exists for that same prefab
[Tooltip("whether or not to create a new pool even if one already exists for that same prefab")]
[MMFCondition("CreateObjectPool", true)]
public bool MutualizePools = false;
protected MMMiniObjectPooler _objectPooler;
protected GameObject _newGameObject;
protected bool _poolCreatedOrFound = false;
/// <summary>
/// On init we create an object pool if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && CreateObjectPool && !_poolCreatedOrFound)
{
if (_objectPooler != null)
{
_objectPooler.DestroyObjectPool();
Destroy(_objectPooler.gameObject);
}
GameObject objectPoolGo = new GameObject();
objectPoolGo.name = this.name+"_ObjectPooler";
_objectPooler = objectPoolGo.AddComponent<MMMiniObjectPooler>();
_objectPooler.GameObjectToPool = GameObjectToInstantiate;
_objectPooler.PoolSize = ObjectPoolSize;
_objectPooler.transform.SetParent(this.transform);
_objectPooler.MutualizeWaitingPools = MutualizePools;
_objectPooler.FillObjectPool();
if ((owner != null) && (objectPoolGo.transform.parent == null))
{
SceneManager.MoveGameObjectToScene(objectPoolGo, owner.scene);
}
_poolCreatedOrFound = true;
}
}
/// <summary>
/// On Play we instantiate the specified object, either from the object pool or from scratch
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (GameObjectToInstantiate == null))
{
return;
}
if (_objectPooler != null)
{
_newGameObject = _objectPooler.GetPooledGameObject();
if (_newGameObject != null)
{
PositionObject(position);
_newGameObject.SetActive(true);
}
}
else
{
_newGameObject = GameObject.Instantiate(GameObjectToInstantiate) as GameObject;
if (_newGameObject != null)
{
SceneManager.MoveGameObjectToScene(_newGameObject, this.gameObject.scene);
PositionObject(position);
}
}
}
protected virtual void PositionObject(Vector3 position)
{
_newGameObject.transform.position = GetPosition(position);
if (AlsoApplyRotation)
{
_newGameObject.transform.rotation = GetRotation();
}
if (AlsoApplyScale)
{
_newGameObject.transform.localScale = GetScale();
}
}
/// <summary>
/// Gets the desired position of that particle system
/// </summary>
/// <param name="position"></param>
/// <returns></returns>
protected virtual Vector3 GetPosition(Vector3 position)
{
switch (PositionMode)
{
case PositionModes.FeedbackPosition:
return this.transform.position + PositionOffset;
case PositionModes.Transform:
return TargetTransform.position + PositionOffset;
case PositionModes.WorldPosition:
return TargetPosition + PositionOffset;
case PositionModes.Script:
return position + PositionOffset;
default:
return position + PositionOffset;
}
}
/// <summary>
/// Gets the desired rotation of that particle system
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
protected virtual Quaternion GetRotation()
{
switch (PositionMode)
{
case PositionModes.FeedbackPosition:
return this.transform.rotation;
case PositionModes.Transform:
return TargetTransform.rotation;
case PositionModes.WorldPosition:
return Quaternion.identity;
case PositionModes.Script:
return this.transform.rotation;
default:
return this.transform.rotation;
}
}
/// <summary>
/// Gets the desired scale of that particle system
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
protected virtual Vector3 GetScale()
{
switch (PositionMode)
{
case PositionModes.FeedbackPosition:
return this.transform.localScale;
case PositionModes.Transform:
return TargetTransform.localScale;
case PositionModes.WorldPosition:
return this.transform.localScale;
case PositionModes.Script:
return this.transform.localScale;
default:
return this.transform.localScale;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bce85594d78e41442a7bfb6ed40e10a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,305 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you control the color and intensity of a Light when played
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback lets you control the color and intensity of a Light in your scene for a certain duration (or instantly).")]
[FeedbackPath("Light")]
public class MMFeedbackLight : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.LightColor; } }
#endif
/// the possible modes for this feedback
public enum Modes { OverTime, Instant, ShakerEvent }
[Header("Light")]
/// the light to affect when playing the feedback
[Tooltip("the light to affect when playing the feedback")]
public Light BoundLight;
/// whether the feedback should affect the light instantly or over a period of time
[Tooltip("whether the feedback should affect the light instantly or over a period of time")]
public Modes Mode = Modes.OverTime;
/// how long the light should change over time
[Tooltip("how long the light should change over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float Duration = 0.2f;
/// whether or not that light should be turned off on start
[Tooltip("whether or not that light should be turned off on start")]
public bool StartsOff = true;
/// whether or not the values should be relative or not
[Tooltip("whether or not the values should be relative or not")]
public bool RelativeValues = true;
/// the channel to broadcast on
[Tooltip("the channel to broadcast on")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public int Channel = 0;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool ResetTargetValuesAfterShake = true;
/// whether or not to broadcast a range to only affect certain shakers
[Tooltip("whether or not to broadcast a range to only affect certain shakers")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool UseRange = false;
/// the range of the event, in units
[Tooltip("the range of the event, in units")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public float EventRange = 100f;
/// the transform to use to broadcast the event as origin point
[Tooltip("the transform to use to broadcast the event as origin point")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public Transform EventOriginTransform;
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
/// if this is true, the light will be disabled when this feedbacks is stopped
[Tooltip("if this is true, the light will be disabled when this feedbacks is stopped")]
public bool DisableOnStop = true;
[Header("Color")]
/// whether or not to modify the color of the light
[Tooltip("whether or not to modify the color of the light")]
public bool ModifyColor = true;
/// the colors to apply to the light over time
[Tooltip("the colors to apply to the light over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public Gradient ColorOverTime;
/// the color to move to in instant mode
[Tooltip("the color to move to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant, (int)Modes.ShakerEvent)]
public Color InstantColor;
[Header("Intensity")]
/// the curve to tween the intensity on
[Tooltip("the curve to tween the intensity on")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public AnimationCurve IntensityCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// the value to remap the intensity curve's 0 to
[Tooltip("the value to remap the intensity curve's 0 to")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float RemapIntensityZero = 0f;
/// the value to remap the intensity curve's 1 to
[Tooltip("the value to remap the intensity curve's 1 to")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float RemapIntensityOne = 1f;
/// the value to move the intensity to in instant mode
[Tooltip("the value to move the intensity to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant)]
public float InstantIntensity;
[Header("Range")]
/// the range to apply to the light over time
[Tooltip("the range to apply to the light over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public AnimationCurve RangeCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// the value to remap the range curve's 0 to
[Tooltip("the value to remap the range curve's 0 to")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float RemapRangeZero = 0f;
/// the value to remap the range curve's 0 to
[Tooltip("the value to remap the range curve's 0 to")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float RemapRangeOne = 10f;
/// the value to move the intensity to in instant mode
[Tooltip("the value to move the intensity to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant)]
public float InstantRange;
[Header("Shadow Strength")]
/// the range to apply to the light over time
[Tooltip("the range to apply to the light over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public AnimationCurve ShadowStrengthCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// the value to remap the shadow strength's curve's 0 to
[Tooltip("the value to remap the shadow strength's curve's 0 to")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float RemapShadowStrengthZero = 0f;
/// the value to remap the shadow strength's curve's 1 to
[Tooltip("the value to remap the shadow strength's curve's 1 to")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public float RemapShadowStrengthOne = 1f;
/// the value to move the shadow strength to in instant mode
[Tooltip("the value to move the shadow strength to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant)]
public float InstantShadowStrength;
protected float _initialRange;
protected float _initialShadowStrength;
protected float _initialIntensity;
protected Coroutine _coroutine;
/// the duration of this feedback is the duration of the light, or 0 if instant
public override float FeedbackDuration { get { return (Mode == Modes.Instant) ? 0f : ApplyTimeMultiplier(Duration); } set { Duration = value; } }
/// <summary>
/// On init we turn the light off if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
_initialRange = BoundLight.range;
_initialShadowStrength = BoundLight.shadowStrength;
_initialIntensity = BoundLight.intensity;
if (EventOriginTransform == null)
{
EventOriginTransform = this.transform;
}
if (Active)
{
if (StartsOff)
{
Turn(false);
}
}
}
/// <summary>
/// On Play we turn our light on and start an over time coroutine if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
Turn(true);
switch (Mode)
{
case Modes.Instant:
BoundLight.intensity = InstantIntensity * intensityMultiplier;
BoundLight.shadowStrength = InstantShadowStrength;
BoundLight.range = InstantRange;
if (ModifyColor)
{
BoundLight.color = InstantColor;
}
break;
case Modes.OverTime:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(LightSequence(intensityMultiplier));
break;
case Modes.ShakerEvent:
MMLightShakeEvent.Trigger(FeedbackDuration, RelativeValues, ModifyColor, ColorOverTime, IntensityCurve,
RemapIntensityZero, RemapIntensityOne, RangeCurve, RemapRangeZero * intensityMultiplier, RemapRangeOne * intensityMultiplier,
ShadowStrengthCurve, RemapShadowStrengthZero, RemapShadowStrengthOne, feedbacksIntensity,
ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake,
UseRange, EventRange, EventOriginTransform.position);
break;
}
}
/// <summary>
/// This coroutine will modify the intensity and color of the light over time
/// </summary>
/// <returns></returns>
protected virtual IEnumerator LightSequence(float intensityMultiplier)
{
IsPlaying = true;
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float remappedTime = MMFeedbacksHelpers.Remap(journey, 0f, FeedbackDuration, 0f, 1f);
SetLightValues(remappedTime, intensityMultiplier);
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
yield return null;
}
SetLightValues(FinalNormalizedTime, intensityMultiplier);
if (StartsOff)
{
Turn(false);
}
IsPlaying = false;
_coroutine = null;
yield return null;
}
/// <summary>
/// Sets the various values on the light on a specified time (between 0 and 1)
/// </summary>
/// <param name="time"></param>
protected virtual void SetLightValues(float time, float intensityMultiplier)
{
float intensity = MMFeedbacksHelpers.Remap(IntensityCurve.Evaluate(time), 0f, 1f, RemapIntensityZero, RemapIntensityOne);
float range = MMFeedbacksHelpers.Remap(RangeCurve.Evaluate(time), 0f, 1f, RemapRangeZero, RemapRangeOne);
float shadowStrength = MMFeedbacksHelpers.Remap(ShadowStrengthCurve.Evaluate(time), 0f, 1f, RemapShadowStrengthZero, RemapShadowStrengthOne);
if (RelativeValues)
{
intensity += _initialIntensity;
shadowStrength += _initialShadowStrength;
range += _initialRange;
}
BoundLight.intensity = intensity * intensityMultiplier;
BoundLight.range = range;
BoundLight.shadowStrength = Mathf.Clamp01(shadowStrength);
if (ModifyColor)
{
BoundLight.color = ColorOverTime.Evaluate(time);
}
}
/// <summary>
/// Turns the light off on stop
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!FeedbackTypeAuthorized)
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
IsPlaying = false;
if (Active && (_coroutine != null))
{
StopCoroutine(_coroutine);
_coroutine = null;
}
if (Active && DisableOnStop)
{
Turn(false);
}
}
/// <summary>
/// Turns the light on or off
/// </summary>
/// <param name="status"></param>
protected virtual void Turn(bool status)
{
BoundLight.gameObject.SetActive(status);
BoundLight.enabled = status;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 139de37acff665248bab15fcf1bbd78c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,100 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will move the current "head" of an MMFeedbacks sequence back to another feedback above in the list.
/// What feedback the head lands on depends on your settings : you can decide to have it loop at last pause, or at the last LoopStart feedback in the list (or both).
/// Furthermore, you can decide to have it loop multiple times and cause a pause when met.
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will move the current 'head' of an MMFeedbacks sequence back to another feedback above in the list. " +
"What feedback the head lands on depends on your settings : you can decide to have it loop at last pause, " +
"or at the last LoopStart feedback in the list (or both). Furthermore, you can decide to have it loop multiple times and cause a pause when met.")]
[FeedbackPath("Loop/Looper")]
public class MMFeedbackLooper : MMFeedbackPause
{
[Header("Loop conditions")]
/// if this is true, this feedback, when met, will cause the MMFeedbacks to reposition its 'head' to the first pause found above it (going from this feedback to the top), or to the start if none is found
[Tooltip("if this is true, this feedback, when met, will cause the MMFeedbacks to reposition its 'head' to the first pause found above it (going from this feedback to the top), or to the start if none is found")]
public bool LoopAtLastPause = true;
/// if this is true, this feedback, when met, will cause the MMFeedbacks to reposition its 'head' to the first LoopStart feedback found above it (going from this feedback to the top), or to the start if none is found
[Tooltip("if this is true, this feedback, when met, will cause the MMFeedbacks to reposition its 'head' to the first LoopStart feedback found above it (going from this feedback to the top), or to the start if none is found")]
public bool LoopAtLastLoopStart = true;
[Header("Loop")]
/// if this is true, the looper will loop forever
[Tooltip("if this is true, the looper will loop forever")]
public bool InfiniteLoop = false;
/// how many times this loop should run
[Tooltip("how many times this loop should run")]
public int NumberOfLoops = 2;
/// the amount of loops left (updated at runtime)
[Tooltip("the amount of loops left (updated at runtime)")]
[MMFReadOnly]
public int NumberOfLoopsLeft = 1;
/// whether we are in an infinite loop at this time or not
[Tooltip("whether we are in an infinite loop at this time or not")]
[MMFReadOnly]
public bool InInfiniteLoop = false;
/// sets the color of this feedback in the inspector
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.LooperColor; } }
#endif
public override bool LooperPause { get { return true; } }
/// the duration of this feedback is the duration of the pause
public override float FeedbackDuration { get { return ApplyTimeMultiplier(PauseDuration); } set { PauseDuration = value; } }
/// <summary>
/// On init we initialize our number of loops left
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
InInfiniteLoop = InfiniteLoop;
NumberOfLoopsLeft = NumberOfLoops;
}
/// <summary>
/// On play we decrease our counter and play our pause
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
NumberOfLoopsLeft--;
StartCoroutine(PlayPause());
}
/// <summary>
/// On custom stop, we exit our infinite loop
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
base.CustomStopFeedback(position, feedbacksIntensity);
InInfiniteLoop = false;
}
/// <summary>
/// On reset we reset our amount of loops left
/// </summary>
protected override void CustomReset()
{
base.CustomReset();
InInfiniteLoop = InfiniteLoop;
NumberOfLoopsLeft = NumberOfLoops;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0d7d28823a5fcb24f93e2098725c6e2f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback can act as a pause but also as a start point for your loops. Add a FeedbackLooper below this (and after a few feedbacks) and your MMFeedbacks will loop between both
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback can act as a pause but also as a start point for your loops. Add a FeedbackLooper below this (and after a few feedbacks) and your MMFeedbacks will loop between both.")]
[FeedbackPath("Loop/Looper Start")]
public class MMFeedbackLooperStart : MMFeedbackPause
{
/// sets the color of this feedback in the inspector
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.LooperStartColor; } }
#endif
public override bool LooperStart { get { return true; } }
/// the duration of this feedback is the duration of the pause
public override float FeedbackDuration { get { return ApplyTimeMultiplier(PauseDuration); } set { PauseDuration = value; } }
/// <summary>
/// Overrides the default value
/// </summary>
protected virtual void Reset()
{
PauseDuration = 0;
}
/// <summary>
/// On play we run our pause
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
StartCoroutine(PlayPause());
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61e9bb2e036c53342a4c946cfb0adb2f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,237 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you change the material of the target renderer everytime it's played.")]
[FeedbackPath("Renderer/Material")]
public class MMFeedbackMaterial : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the duration of this feedback is the duration of the shake
public override float FeedbackDuration { get { return (InterpolateTransition) ? TransitionDuration : 0f; } set { if (InterpolateTransition) { TransitionDuration = value; } } }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.RendererColor; } }
#endif
/// the possible methods to switch materials
public enum Methods { Sequential, Random }
[Header("Material")]
/// the renderer to change material on
[Tooltip("the renderer to change material on")]
public Renderer TargetRenderer;
/// the list of material indexes we want to change on the target renderer. If left empty, will only target the material at index 0
[FormerlySerializedAs("MaterialIndexes")] [Tooltip("the list of material indexes we want to change on the target renderer. If left empty, will only target the material at index 0")]
public int[] RendererMaterialIndexes;
[Header("Material Change")]
/// the selected method
[Tooltip("the selected method")]
public Methods Method;
/// whether or not the sequential order should loop
[MMFEnumCondition("Method", (int)Methods.Sequential)]
[Tooltip("whether or not the sequential order should loop")]
public bool Loop = true;
/// whether or not to always pick a new material in random mode
[MMFEnumCondition("Method", (int)Methods.Random)]
[Tooltip("whether or not to always pick a new material in random mode")]
public bool AlwaysNewMaterial = true;
/// the initial index to start with
[Tooltip("the initial index to start with")]
public int InitialIndex = 0;
/// the list of materials to pick from
[Tooltip("the list of materials to pick from")]
public List<Material> Materials;
[Header("Interpolation")]
/// whether or not to interpolate between 2 materials
/// IMPORTANT : this will only work for materials that share the same shader and texture (see https://docs.unity3d.com/ScriptReference/Material.Lerp.html)
public bool InterpolateTransition = false;
/// the duration of the interpolation, in seconds
public float TransitionDuration = 1f;
/// the animation curve to interpolate the transition on
public AnimationCurve TransitionCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
public virtual float GetTime() { return (Timing.TimescaleMode == TimescaleModes.Scaled) ? Time.time : Time.unscaledTime; }
public virtual float GetDeltaTime() { return (Timing.TimescaleMode == TimescaleModes.Scaled) ? Time.deltaTime : Time.unscaledDeltaTime; }
protected int _currentIndex;
protected float _startedAt;
protected Coroutine[] _coroutines;
protected Material[] _tempMaterials;
/// <summary>
/// On init, grabs the current index
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
_currentIndex = InitialIndex;
_tempMaterials = new Material[TargetRenderer.materials.Length];
if (RendererMaterialIndexes == null)
{
RendererMaterialIndexes = new int[1];
}
if (RendererMaterialIndexes.Length == 0)
{
RendererMaterialIndexes = new int[1];
RendererMaterialIndexes[0] = 0;
}
_coroutines = new Coroutine[RendererMaterialIndexes.Length];
}
/// <summary>
/// On play feedback, we change the material if possible
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (Materials.Count == 0)
{
Debug.LogError("[MMFeedbackMaterial on " + this.name + "] The Materials array is empty.");
return;
}
int newIndex = DetermineNextIndex();
if (Materials[newIndex] == null)
{
Debug.LogError("[MMFeedbackMaterial on " + this.name + "] Attempting to switch to a null material.");
return;
}
if (InterpolateTransition)
{
for (int i = 0; i < RendererMaterialIndexes.Length; i++)
{
_coroutines[i] = StartCoroutine(TransitionMaterial(TargetRenderer.materials[RendererMaterialIndexes[i]], Materials[newIndex], RendererMaterialIndexes[i]));
}
}
else
{
ApplyMaterial(Materials[newIndex]);
}
}
/// <summary>
/// Applies the new material to all indexes
/// </summary>
/// <param name="material"></param>
protected virtual void ApplyMaterial(Material material)
{
_tempMaterials = TargetRenderer.materials;
for (int i = 0; i < RendererMaterialIndexes.Length; i++)
{
_tempMaterials[RendererMaterialIndexes[i]] = material;
}
TargetRenderer.materials = _tempMaterials;
}
/// <summary>
/// Lerps to destination material for all indexes
/// </summary>
/// <param name="fromMaterial"></param>
/// <param name="toMaterial"></param>
/// <param name="t"></param>
/// <param name="materialIndex"></param>
protected virtual void LerpMaterial(Material fromMaterial, Material toMaterial, float t, int materialIndex)
{
_tempMaterials = TargetRenderer.materials;
for (int i = 0; i < RendererMaterialIndexes.Length; i++)
{
_tempMaterials[materialIndex].Lerp(fromMaterial, toMaterial, t);
}
TargetRenderer.materials = _tempMaterials;
}
/// <summary>
/// A coroutine used to interpolate between materials
/// </summary>
/// <param name="originalMaterial"></param>
/// <param name="newMaterial"></param>
/// <returns></returns>
protected virtual IEnumerator TransitionMaterial(Material originalMaterial, Material newMaterial, int materialIndex)
{
IsPlaying = true;
_startedAt = GetTime();
while (GetTime() - _startedAt < TransitionDuration)
{
float time = MMFeedbacksHelpers.Remap(GetTime() - _startedAt, 0f, TransitionDuration, 0f, 1f);
float t = TransitionCurve.Evaluate(time);
LerpMaterial(originalMaterial, newMaterial, t, materialIndex);
yield return null;
}
float finalt = TransitionCurve.Evaluate(1f);
LerpMaterial(originalMaterial, newMaterial, finalt, materialIndex);
IsPlaying = false;
}
/// <summary>
/// Determines the new material to pick
/// </summary>
/// <returns></returns>
protected virtual int DetermineNextIndex()
{
switch(Method)
{
case Methods.Random:
int random = Random.Range(0, Materials.Count);
if (AlwaysNewMaterial)
{
while (_currentIndex == random)
{
random = Random.Range(0, Materials.Count);
}
}
_currentIndex = random;
return _currentIndex;
case Methods.Sequential:
_currentIndex++;
if (_currentIndex >= Materials.Count)
{
_currentIndex = Loop ? 0 : _currentIndex;
}
return _currentIndex;
}
return 0;
}
/// <summary>
/// Stops the transition on stop if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
base.CustomStopFeedback(position, feedbacksIntensity);
if (Active && FeedbackTypeAuthorized && (_coroutines != null))
{
IsPlaying = false;
for (int i = 0; i < RendererMaterialIndexes.Length; i++)
{
if (_coroutines[i] != null)
{
StopCoroutine(_coroutines[i]);
}
_coroutines[i] = null;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8cfccef02abb17a438a2bcccd7133075
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,170 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using Random = UnityEngine.Random;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will play the associated particles system on play, and stop it on stop
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will simply play the specified ParticleSystem (from your scene) when played.")]
[FeedbackPath("Particles/Particles Play")]
public class MMFeedbackParticles : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.ParticlesColor; } }
#endif
public enum Modes { Play, Stop, Pause }
[Header("Bound Particles")]
/// whether to Play, Stop or Pause the target particle system when that feedback is played
[Tooltip("whether to Play, Stop or Pause the target particle system when that feedback is played")]
public Modes Mode = Modes.Play;
/// the particle system to play with this feedback
[Tooltip("the particle system to play with this feedback")]
public ParticleSystem BoundParticleSystem;
/// a list of (optional) particle systems
[Tooltip("a list of (optional) particle systems")]
public List<ParticleSystem> RandomParticleSystems;
/// if this is true, the particles will be moved to the position passed in parameters
[Tooltip("if this is true, the particles will be moved to the position passed in parameters")]
public bool MoveToPosition = false;
/// if this is true, the particle system's object will be set active on play
[Tooltip("if this is true, the particle system's object will be set active on play")]
public bool ActivateOnPlay = false;
/// <summary>
/// On init we stop our particle system
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
StopParticles();
}
/// <summary>
/// On play we play our particle system
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
PlayParticles(position);
}
/// <summary>
/// On Stop, stops the particle system
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
StopParticles();
}
/// <summary>
/// On Reset, stops the particle system
/// </summary>
protected override void CustomReset()
{
base.CustomReset();
if (InCooldown)
{
return;
}
StopParticles();
}
/// <summary>
/// Plays a particle system
/// </summary>
/// <param name="position"></param>
protected virtual void PlayParticles(Vector3 position)
{
if (MoveToPosition)
{
BoundParticleSystem.transform.position = position;
foreach (ParticleSystem system in RandomParticleSystems)
{
system.transform.position = position;
}
}
if (ActivateOnPlay)
{
BoundParticleSystem.gameObject.SetActive(true);
foreach (ParticleSystem system in RandomParticleSystems)
{
system.gameObject.SetActive(true);
}
}
if (RandomParticleSystems.Count > 0)
{
int random = Random.Range(0, RandomParticleSystems.Count);
switch (Mode)
{
case Modes.Play:
RandomParticleSystems[random].Play();
break;
case Modes.Stop:
RandomParticleSystems[random].Stop();
break;
case Modes.Pause:
RandomParticleSystems[random].Pause();
break;
}
return;
}
else if (BoundParticleSystem != null)
{
switch (Mode)
{
case Modes.Play:
BoundParticleSystem?.Play();
break;
case Modes.Stop:
BoundParticleSystem?.Stop();
break;
case Modes.Pause:
BoundParticleSystem?.Pause();
break;
}
}
}
/// <summary>
/// Stops all particle systems
/// </summary>
protected virtual void StopParticles()
{
foreach(ParticleSystem system in RandomParticleSystems)
{
system?.Stop();
}
if (BoundParticleSystem != null)
{
BoundParticleSystem.Stop();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c27131831afa28b499cb120fc9059997
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,368 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.SceneManagement;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will instantiate a particle system and play/stop it when playing/stopping the feedback
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will instantiate the specified ParticleSystem at the specified position on Start or on Play, optionally nesting them.")]
[FeedbackPath("Particles/Particles Instantiation")]
public class MMFeedbackParticlesInstantiation : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.ParticlesColor; } }
#endif
/// the different ways to position the instantiated object :
/// - FeedbackPosition : object will be instantiated at the position of the feedback, plus an optional offset
/// - Transform : the object will be instantiated at the specified Transform's position, plus an optional offset
/// - WorldPosition : the object will be instantiated at the specified world position vector, plus an optional offset
/// - Script : the position passed in parameters when calling the feedback
public enum PositionModes { FeedbackPosition, Transform, WorldPosition, Script }
/// the possible delivery modes
/// - cached : will cache a copy of the particle system and reuse it
/// - on demand : will instantiate a new particle system for every play
public enum Modes { Cached, OnDemand }
[Header("Particles Instantiation")]
/// whether the particle system should be cached or created on demand the first time
[Tooltip("whether the particle system should be cached or created on demand the first time")]
public Modes Mode = Modes.Cached;
/// if this is false, a brand new particle system will be created every time
[Tooltip("if this is false, a brand new particle system will be created every time")]
[MMFEnumCondition("Mode", (int)Modes.OnDemand)]
public bool CachedRecycle = true;
/// the particle system to spawn
[Tooltip("the particle system to spawn")]
public ParticleSystem ParticlesPrefab;
/// the possible random particle systems
[Tooltip("the possible random particle systems")]
public List<ParticleSystem> RandomParticlePrefabs;
/// if this is true, the particle system game object will be activated on Play, useful if you've somehow disabled it in a past Play
[Tooltip("if this is true, the particle system game object will be activated on Play, useful if you've somehow disabled it in a past Play")]
public bool ForceSetActiveOnPlay = false;
[Header("Position")]
/// the selected position mode
[Tooltip("the selected position mode")]
public PositionModes PositionMode = PositionModes.FeedbackPosition;
/// the position at which to spawn this particle system
[Tooltip("the position at which to spawn this particle system")]
[MMFEnumCondition("PositionMode", (int)PositionModes.Transform)]
public Transform InstantiateParticlesPosition;
/// the world position to move to when in WorldPosition mode
[Tooltip("the world position to move to when in WorldPosition mode")]
[MMFEnumCondition("PositionMode", (int)PositionModes.WorldPosition)]
public Vector3 TargetWorldPosition;
/// an offset to apply to the instantiation position
[Tooltip("an offset to apply to the instantiation position")]
public Vector3 Offset;
/// whether or not the particle system should be nested in hierarchy or floating on its own
[Tooltip("whether or not the particle system should be nested in hierarchy or floating on its own")]
[MMFEnumCondition("PositionMode", (int)PositionModes.Transform, (int)PositionModes.FeedbackPosition)]
public bool NestParticles = true;
/// whether or not to also apply rotation
[Tooltip("whether or not to also apply rotation")]
public bool ApplyRotation = false;
/// whether or not to also apply scale
[Tooltip("whether or not to also apply scale")]
public bool ApplyScale = false;
protected ParticleSystem _instantiatedParticleSystem;
protected List<ParticleSystem> _instantiatedRandomParticleSystems;
/// <summary>
/// On init, instantiates the particle system, positions it and nests it if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
if (!Active)
{
return;
}
if (Mode == Modes.Cached)
{
InstantiateParticleSystem();
}
}
/// <summary>
/// Instantiates the particle system
/// </summary>
protected virtual void InstantiateParticleSystem()
{
if (CachedRecycle)
{
if (_instantiatedParticleSystem != null)
{
PositionParticleSystem(_instantiatedParticleSystem);
return;
}
}
Transform newParent = null;
if (NestParticles)
{
if (PositionMode == PositionModes.FeedbackPosition)
{
newParent = this.transform;
}
if (PositionMode == PositionModes.Transform)
{
newParent = InstantiateParticlesPosition;
}
}
if (RandomParticlePrefabs.Count > 0)
{
if (Mode == Modes.Cached)
{
_instantiatedRandomParticleSystems = new List<ParticleSystem>();
foreach(ParticleSystem system in RandomParticlePrefabs)
{
ParticleSystem newSystem = GameObject.Instantiate(system, newParent) as ParticleSystem;
if (newParent == null)
{
SceneManager.MoveGameObjectToScene(newSystem.gameObject, this.gameObject.scene);
}
_instantiatedRandomParticleSystems.Add(newSystem);
}
}
else
{
int random = Random.Range(0, RandomParticlePrefabs.Count);
_instantiatedParticleSystem = GameObject.Instantiate(RandomParticlePrefabs[random], newParent) as ParticleSystem;
if (newParent == null)
{
SceneManager.MoveGameObjectToScene(_instantiatedParticleSystem.gameObject, this.gameObject.scene);
}
}
}
else
{
_instantiatedParticleSystem = GameObject.Instantiate(ParticlesPrefab, newParent) as ParticleSystem;
if (newParent == null)
{
SceneManager.MoveGameObjectToScene(_instantiatedParticleSystem.gameObject, this.gameObject.scene);
}
}
if (_instantiatedParticleSystem != null)
{
PositionParticleSystem(_instantiatedParticleSystem);
}
if ((_instantiatedRandomParticleSystems != null) && (_instantiatedRandomParticleSystems.Count > 0))
{
foreach (ParticleSystem system in _instantiatedRandomParticleSystems)
{
PositionParticleSystem(system);
}
}
}
protected virtual void PositionParticleSystem(ParticleSystem system)
{
if (InstantiateParticlesPosition == null)
{
if (Owner != null)
{
InstantiateParticlesPosition = Owner.transform;
}
}
if (system != null)
{
system.Stop();
system.transform.position = GetPosition(this.transform.position);
if (ApplyRotation)
{
system.transform.rotation = GetRotation(this.transform);
}
if (ApplyScale)
{
system.transform.localScale = GetScale(this.transform);
}
system.Clear();
}
}
/// <summary>
/// Gets the desired rotation of that particle system
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
protected virtual Quaternion GetRotation(Transform target)
{
switch (PositionMode)
{
case PositionModes.FeedbackPosition:
return this.transform.rotation;
case PositionModes.Transform:
return InstantiateParticlesPosition.rotation;
case PositionModes.WorldPosition:
return Quaternion.identity;
case PositionModes.Script:
return this.transform.rotation;
default:
return this.transform.rotation;
}
}
/// <summary>
/// Gets the desired scale of that particle system
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
protected virtual Vector3 GetScale(Transform target)
{
switch (PositionMode)
{
case PositionModes.FeedbackPosition:
return this.transform.localScale;
case PositionModes.Transform:
return InstantiateParticlesPosition.localScale;
case PositionModes.WorldPosition:
return this.transform.localScale;
case PositionModes.Script:
return this.transform.localScale;
default:
return this.transform.localScale;
}
}
/// <summary>
/// Gets the position
/// </summary>
/// <param name="position"></param>
/// <returns></returns>
protected virtual Vector3 GetPosition(Vector3 position)
{
switch (PositionMode)
{
case PositionModes.FeedbackPosition:
return this.transform.position + Offset;
case PositionModes.Transform:
return InstantiateParticlesPosition.position + Offset;
case PositionModes.WorldPosition:
return TargetWorldPosition + Offset;
case PositionModes.Script:
return position + Offset;
default:
return position + Offset;
}
}
/// <summary>
/// On Play, plays the feedback
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (Mode == Modes.OnDemand)
{
InstantiateParticleSystem();
}
if (_instantiatedParticleSystem != null)
{
if (ForceSetActiveOnPlay)
{
_instantiatedParticleSystem.gameObject.SetActive(true);
}
_instantiatedParticleSystem.Stop();
_instantiatedParticleSystem.transform.position = GetPosition(position);
_instantiatedParticleSystem.Play();
}
if ((_instantiatedRandomParticleSystems != null) && (_instantiatedRandomParticleSystems.Count > 0))
{
foreach (ParticleSystem system in _instantiatedRandomParticleSystems)
{
if (ForceSetActiveOnPlay)
{
system.gameObject.SetActive(true);
}
system.Stop();
system.transform.position = GetPosition(position);
}
int random = Random.Range(0, _instantiatedRandomParticleSystems.Count);
_instantiatedRandomParticleSystems[random].Play();
}
}
/// <summary>
/// On Stop, stops the feedback
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (_instantiatedParticleSystem != null)
{
_instantiatedParticleSystem?.Stop();
}
if ((_instantiatedRandomParticleSystems != null) && (_instantiatedRandomParticleSystems.Count > 0))
{
foreach(ParticleSystem system in _instantiatedRandomParticleSystems)
{
system.Stop();
}
}
}
/// <summary>
/// On Reset, stops the feedback
/// </summary>
protected override void CustomReset()
{
base.CustomReset();
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (InCooldown)
{
return;
}
if (_instantiatedParticleSystem != null)
{
_instantiatedParticleSystem?.Stop();
}
if ((_instantiatedRandomParticleSystems != null) && (_instantiatedRandomParticleSystems.Count > 0))
{
foreach (ParticleSystem system in _instantiatedRandomParticleSystems)
{
system.Stop();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cdfe4b9b079619143a9748eeee75e698
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will cause a pause when met, preventing any other feedback lower in the sequence to run until it's complete.
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will cause a pause when met, preventing any other feedback lower in the sequence to run until it's complete.")]
[FeedbackPath("Pause/Pause")]
public class MMFeedbackPause : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.PauseColor; } }
#endif
public override IEnumerator Pause { get { return PauseWait(); } }
[Header("Pause")]
/// the duration of the pause, in seconds
[Tooltip("the duration of the pause, in seconds")]
public float PauseDuration = 1f;
public bool RandomizePauseDuration = false;
[MMFCondition("RandomizePauseDuration", true)]
public float MinPauseDuration = 1f;
[MMFCondition("RandomizePauseDuration", true)]
public float MaxPauseDuration = 3f;
[MMFCondition("RandomizePauseDuration", true)]
public bool RandomizeOnEachPlay = true;
/// if this is true, you'll need to call the Resume() method on the host MMFeedbacks for this pause to stop, and the rest of the sequence to play
[Tooltip("if this is true, you'll need to call the Resume() method on the host MMFeedbacks for this pause to stop, and the rest of the sequence to play")]
public bool ScriptDriven = false;
/// if this is true, a script driven pause will resume after its AutoResumeAfter delay, whether it has been manually resumed or not
[Tooltip("if this is true, a script driven pause will resume after its AutoResumeAfter delay, whether it has been manually resumed or not")]
[MMFCondition("ScriptDriven", true)]
public bool AutoResume = false;
/// the duration after which to auto resume, regardless of manual resume calls beforehand
[Tooltip("the duration after which to auto resume, regardless of manual resume calls beforehand")]
[MMFCondition("AutoResume", true)]
public float AutoResumeAfter = 0.25f;
/// the duration of this feedback is the duration of the pause
public override float FeedbackDuration { get { return ApplyTimeMultiplier(PauseDuration); } set { PauseDuration = value; } }
/// <summary>
/// An IEnumerator used to wait for the duration of the pause, on scaled or unscaled time
/// </summary>
/// <returns></returns>
protected virtual IEnumerator PauseWait()
{
if (Timing.TimescaleMode == TimescaleModes.Scaled)
{
return MMFeedbacksCoroutine.WaitFor(PauseDuration);
}
else
{
return MMFeedbacksCoroutine.WaitForUnscaled(PauseDuration);
}
}
/// <summary>
/// On init we cache our wait for seconds
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
ScriptDrivenPause = ScriptDriven;
ScriptDrivenPauseAutoResume = AutoResume ? AutoResumeAfter : -1f;
if (RandomizePauseDuration)
{
PauseDuration = Random.Range(MinPauseDuration, MaxPauseDuration);
}
}
/// <summary>
/// On play we trigger our pause
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (RandomizePauseDuration && RandomizeOnEachPlay)
{
PauseDuration = Random.Range(MinPauseDuration, MaxPauseDuration);
}
StartCoroutine(PlayPause());
}
/// <summary>
/// Pause coroutine
/// </summary>
/// <returns></returns>
protected virtual IEnumerator PlayPause()
{
yield return Pause;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 66650ffe68eb1f548acc774ac2db1b80
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,399 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// this feedback will let you animate the position of
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will animate the target object's position over time, for the specified duration, from the chosen initial position to the chosen destination. These can either be relative Vector3 offsets from the Feedback's position, or Transforms. If you specify transforms, the Vector3 values will be ignored.")]
[FeedbackPath("Transform/Position")]
public class MMFeedbackPosition : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.TransformColor; } }
#endif
public enum Spaces { World, Local, RectTransform }
public enum Modes { AtoB, AlongCurve, ToDestination }
public enum TimeScales { Scaled, Unscaled }
[Header("Position Target")]
/// the object this feedback will animate the position for
[Tooltip("the object this feedback will animate the position for")]
public GameObject AnimatePositionTarget;
[Header("Animation")]
/// the mode this animation should follow (either going from A to B, or moving along a curve)
[Tooltip("the mode this animation should follow (either going from A to B, or moving along a curve)")]
public Modes Mode = Modes.AtoB;
/// whether this feedback should play in scaled or unscaled time
[Tooltip("whether this feedback should play in scaled or unscaled time")]
public TimeScales TimeScale = TimeScales.Scaled;
/// the space in which to move the position in
[Tooltip("the space in which to move the position in")]
public Spaces Space = Spaces.World;
/// the duration of the animation on play
[Tooltip("the duration of the animation on play")]
public float AnimatePositionDuration = 0.2f;
/// the acceleration of the movement
[Tooltip("the acceleration of the movement")]
[MMFEnumCondition("Mode", (int)Modes.AtoB, (int)Modes.ToDestination)]
public AnimationCurve AnimatePositionCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
/// the value to remap the curve's 0 value to
[MMFEnumCondition("Mode", (int)Modes.AlongCurve)]
[Tooltip("the value to remap the curve's 0 value to")]
public float RemapCurveZero = 0f;
/// the value to remap the curve's 1 value to
[Tooltip("the value to remap the curve's 1 value to")]
[MMFEnumCondition("Mode", (int)Modes.AlongCurve)]
[FormerlySerializedAs("CurveMultiplier")]
public float RemapCurveOne = 1f;
/// if this is true, the x position will be animated
[Tooltip("if this is true, the x position will be animated")]
[MMFEnumCondition("Mode", (int)Modes.AlongCurve)]
public bool AnimateX;
/// the acceleration of the movement
[Tooltip("the acceleration of the movement")]
[MMFCondition("AnimateX", true)]
public AnimationCurve AnimatePositionCurveX = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(0.6f, -1f), new Keyframe(1, 0f));
/// if this is true, the y position will be animated
[Tooltip("if this is true, the y position will be animated")]
[MMFEnumCondition("Mode", (int)Modes.AlongCurve)]
public bool AnimateY;
/// the acceleration of the movement
[Tooltip("the acceleration of the movement")]
[MMFCondition("AnimateY", true)]
public AnimationCurve AnimatePositionCurveY = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(0.6f, -1f), new Keyframe(1, 0f));
/// if this is true, the z position will be animated
[Tooltip("if this is true, the z position will be animated")]
[MMFEnumCondition("Mode", (int)Modes.AlongCurve)]
public bool AnimateZ;
/// the acceleration of the movement
[Tooltip("the acceleration of the movement")]
[MMFCondition("AnimateZ", true)]
public AnimationCurve AnimatePositionCurveZ = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(0.6f, -1f), new Keyframe(1, 0f));
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
[Header("Positions")]
/// if this is true, the initial position won't be added to init and destination
[Tooltip("if this is true, the initial position won't be added to init and destination")]
public bool RelativePosition = true;
/// if this is true, initial and destination positions will be recomputed on every play
[Tooltip("if this is true, initial and destination positions will be recomputed on every play")]
public bool DeterminePositionsOnPlay = false;
/// the initial position
[Tooltip("the initial position")]
[MMFEnumCondition("Mode", (int)Modes.AtoB, (int)Modes.AlongCurve)]
public Vector3 InitialPosition = Vector3.zero;
/// the destination position
[Tooltip("the destination position")]
[MMFEnumCondition("Mode", (int)Modes.AtoB, (int)Modes.ToDestination)]
public Vector3 DestinationPosition = Vector3.one;
/// the initial transform - if set, takes precedence over the Vector3 above
[Tooltip("the initial transform - if set, takes precedence over the Vector3 above")]
[MMFEnumCondition("Mode", (int)Modes.AtoB, (int)Modes.AlongCurve)]
public Transform InitialPositionTransform;
/// the destination transform - if set, takes precedence over the Vector3 above
[Tooltip("the destination transform - if set, takes precedence over the Vector3 above")]
[MMFEnumCondition("Mode", (int)Modes.AtoB, (int)Modes.ToDestination)]
public Transform DestinationPositionTransform;
/// the duration of this feedback is the duration of its animation
public override float FeedbackDuration { get { return ApplyTimeMultiplier(AnimatePositionDuration); } set { AnimatePositionDuration = value; } }
protected Vector3 _newPosition;
protected RectTransform _rectTransform;
protected Vector3 _initialPosition;
protected Vector3 _destinationPosition;
protected Coroutine _coroutine;
/// <summary>
/// On init, we set our initial and destination positions (transform will take precedence over vector3s)
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active)
{
if (AnimatePositionTarget == null)
{
Debug.LogWarning("The animate position target for " + this + " is null, you have to define it in the inspector");
return;
}
if (Space == Spaces.RectTransform)
{
_rectTransform = AnimatePositionTarget.GetComponent<RectTransform>();
}
if (!DeterminePositionsOnPlay)
{
DeterminePositions();
}
}
}
protected virtual void DeterminePositions()
{
if (DeterminePositionsOnPlay && RelativePosition && (InitialPosition != Vector3.zero))
{
return;
}
if (Mode != Modes.ToDestination)
{
if (InitialPositionTransform != null)
{
InitialPosition = GetPosition(InitialPositionTransform);
}
else
{
InitialPosition = RelativePosition ? GetPosition(AnimatePositionTarget.transform) + InitialPosition : GetPosition(AnimatePositionTarget.transform);
}
if (DestinationPositionTransform != null)
{
DestinationPosition = GetPosition(DestinationPositionTransform);
}
else
{
DestinationPosition = RelativePosition ? GetPosition(AnimatePositionTarget.transform) + DestinationPosition : DestinationPosition;
}
}
}
/// <summary>
/// On Play, we move our object from A to B
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (AnimatePositionTarget == null))
{
return;
}
if (isActiveAndEnabled || _hostMMFeedbacks.AutoPlayOnEnable)
{
if (DeterminePositionsOnPlay && NormalPlayDirection)
{
DeterminePositions();
}
switch (Mode)
{
case Modes.ToDestination:
_initialPosition = GetPosition(AnimatePositionTarget.transform);
_destinationPosition = RelativePosition ? _initialPosition + DestinationPosition : DestinationPosition;
if (DestinationPositionTransform != null)
{
_destinationPosition = GetPosition(DestinationPositionTransform);
}
_coroutine = StartCoroutine(MoveFromTo(AnimatePositionTarget, _initialPosition, _destinationPosition, FeedbackDuration, AnimatePositionCurve));
break;
case Modes.AtoB:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(MoveFromTo(AnimatePositionTarget, InitialPosition, DestinationPosition, FeedbackDuration, AnimatePositionCurve));
break;
case Modes.AlongCurve:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
_coroutine = StartCoroutine(MoveAlongCurve(AnimatePositionTarget, InitialPosition, FeedbackDuration, intensityMultiplier));
break;
}
}
}
/// <summary>
/// Moves the object along a curve
/// </summary>
/// <param name="movingObject"></param>
/// <param name="pointA"></param>
/// <param name="pointB"></param>
/// <param name="duration"></param>
/// <param name="curve"></param>
/// <returns></returns>
protected virtual IEnumerator MoveAlongCurve(GameObject movingObject, Vector3 initialPosition, float duration, float intensityMultiplier)
{
IsPlaying = true;
float journey = NormalPlayDirection ? 0f : duration;
while ((journey >= 0) && (journey <= duration) && (duration > 0))
{
float percent = Mathf.Clamp01(journey / duration);
ComputeNewCurvePosition(movingObject, initialPosition, percent, intensityMultiplier);
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
ComputeNewCurvePosition(movingObject, initialPosition, FinalNormalizedTime, intensityMultiplier);
_coroutine = null;
IsPlaying = false;
yield break;
}
/// <summary>
/// Evaluates the position curves and computes the new position
/// </summary>
/// <param name="movingObject"></param>
/// <param name="initialPosition"></param>
/// <param name="percent"></param>
protected virtual void ComputeNewCurvePosition(GameObject movingObject, Vector3 initialPosition, float percent, float intensityMultiplier)
{
float newValueX = AnimatePositionCurveX.Evaluate(percent);
float newValueY = AnimatePositionCurveY.Evaluate(percent);
float newValueZ = AnimatePositionCurveZ.Evaluate(percent);
newValueX = MMFeedbacksHelpers.Remap(newValueX, 0f, 1f, RemapCurveZero * intensityMultiplier, RemapCurveOne * intensityMultiplier);
newValueY = MMFeedbacksHelpers.Remap(newValueY, 0f, 1f, RemapCurveZero * intensityMultiplier, RemapCurveOne * intensityMultiplier);
newValueZ = MMFeedbacksHelpers.Remap(newValueZ, 0f, 1f, RemapCurveZero * intensityMultiplier, RemapCurveOne * intensityMultiplier);
_newPosition = initialPosition;
if (RelativePosition)
{
_newPosition.x = AnimateX ? initialPosition.x + newValueX : initialPosition.x;
_newPosition.y = AnimateY ? initialPosition.y + newValueY : initialPosition.y;
_newPosition.z = AnimateZ ? initialPosition.z + newValueZ : initialPosition.z;
}
else
{
_newPosition.x = AnimateX ? newValueX : initialPosition.x;
_newPosition.y = AnimateY ? newValueY : initialPosition.y;
_newPosition.z = AnimateZ ? newValueZ : initialPosition.z;
}
SetPosition(movingObject.transform, _newPosition);
}
/// <summary>
/// Moves an object from point A to point B in a given time
/// </summary>
/// <param name="movingObject">Moving object.</param>
/// <param name="pointA">Point a.</param>
/// <param name="pointB">Point b.</param>
/// <param name="duration">Time.</param>
protected virtual IEnumerator MoveFromTo(GameObject movingObject, Vector3 pointA, Vector3 pointB, float duration, AnimationCurve curve = null)
{
IsPlaying = true;
float journey = NormalPlayDirection ? 0f : duration;
while ((journey >= 0) && (journey <= duration) && (duration > 0))
{
float percent = Mathf.Clamp01(journey / duration);
_newPosition = Vector3.LerpUnclamped(pointA, pointB, curve.Evaluate(percent));
SetPosition(movingObject.transform, _newPosition);
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
// set final position
if (NormalPlayDirection)
{
SetPosition(movingObject.transform, pointB);
}
else
{
SetPosition(movingObject.transform, pointA);
}
_coroutine = null;
IsPlaying = false;
yield break;
}
/// <summary>
/// Gets the world, local or anchored position
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
protected virtual Vector3 GetPosition(Transform target)
{
switch (Space)
{
case Spaces.World:
return target.position;
case Spaces.Local:
return target.localPosition;
case Spaces.RectTransform:
return target.gameObject.GetComponent<RectTransform>().anchoredPosition;
}
return Vector3.zero;
}
/// <summary>
/// Sets the position, localposition or anchoredposition of the target
/// </summary>
/// <param name="target"></param>
/// <param name="newPosition"></param>
protected virtual void SetPosition(Transform target, Vector3 newPosition)
{
switch (Space)
{
case Spaces.World:
target.position = newPosition;
break;
case Spaces.Local:
target.localPosition = newPosition;
break;
case Spaces.RectTransform:
_rectTransform.anchoredPosition = newPosition;
break;
}
}
/// <summary>
/// On stop, we interrupt movement if it was active
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (_coroutine == null))
{
return;
}
IsPlaying = false;
StopCoroutine(_coroutine);
_coroutine = null;
}
/// <summary>
/// On disable we reset our coroutine
/// </summary>
protected virtual void OnDisable()
{
_coroutine = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 376d98efc7809f24693ecc03cdc3e05e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// this feedback will let you apply forces and torques (relative or not) to a Rigidbody
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you apply forces and torques (relative or not) to a Rigidbody.")]
[FeedbackPath("GameObject/Rigidbody")]
public class MMFeedbackRigidbody : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
public enum Modes { AddForce, AddRelativeForce, AddTorque, AddRelativeTorque }
[Header("Rigidbody")]
/// the rigidbody to target on play
[Tooltip("the rigidbody to target on play")]
public Rigidbody TargetRigidbody;
/// the selected mode for this feedback
[Tooltip("the selected mode for this feedback")]
public Modes Mode = Modes.AddForce;
/// the min force or torque to apply
[Tooltip("the min force or torque to apply")]
public Vector3 MinForce;
/// the max force or torque to apply
[Tooltip("the max force or torque to apply")]
public Vector3 MaxForce;
/// the force mode to apply
[Tooltip("the force mode to apply")]
public ForceMode AppliedForceMode = ForceMode.Impulse;
protected Vector3 _force;
/// <summary>
/// On Custom Play, we apply our force or torque to the target rigidbody
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetRigidbody == null))
{
return;
}
_force.x = Random.Range(MinForce.x, MaxForce.x);
_force.y = Random.Range(MinForce.y, MaxForce.y);
_force.z = Random.Range(MinForce.z, MaxForce.z);
if (!Timing.ConstantIntensity)
{
_force *= feedbacksIntensity;
}
switch (Mode)
{
case Modes.AddForce:
TargetRigidbody.AddForce(_force, AppliedForceMode);
break;
case Modes.AddRelativeForce:
TargetRigidbody.AddRelativeForce(_force, AppliedForceMode);
break;
case Modes.AddTorque:
TargetRigidbody.AddTorque(_force, AppliedForceMode);
break;
case Modes.AddRelativeTorque:
TargetRigidbody.AddRelativeTorque(_force, AppliedForceMode);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a06314a2f6630f4489f2595e0e58c9c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// this feedback will let you apply forces and torques (relative or not) to a Rigidbody
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you apply forces and torques (relative or not) to a Rigidbody.")]
[FeedbackPath("GameObject/Rigidbody2D")]
public class MMFeedbackRigidbody2D : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
public enum Modes { AddForce, AddRelativeForce, AddTorque}
[Header("Rigidbody")]
/// the rigidbody to target on play
[Tooltip("the rigidbody to target on play")]
public Rigidbody2D TargetRigidbody2D;
/// the selected mode for this feedback
[Tooltip("the selected mode for this feedback")]
public Modes Mode = Modes.AddForce;
/// the min force or torque to apply
[Tooltip("the min force or torque to apply")]
[MMFEnumCondition("Mode", (int)Modes.AddForce, (int)Modes.AddRelativeForce)]
public Vector2 MinForce;
/// the max force or torque to apply
[Tooltip("the max force or torque to apply")]
[MMFEnumCondition("Mode", (int)Modes.AddForce, (int)Modes.AddRelativeForce)]
public Vector2 MaxForce;
/// the min torque to apply to this rigidbody on play
[Tooltip("the min torque to apply to this rigidbody on play")]
[MMFEnumCondition("Mode", (int)Modes.AddTorque)]
public float MinTorque;
/// the max torque to apply to this rigidbody on play
[Tooltip("the max torque to apply to this rigidbody on play")]
[MMFEnumCondition("Mode", (int)Modes.AddTorque)]
public float MaxTorque;
/// the force mode to apply
[Tooltip("the force mode to apply")]
public ForceMode2D AppliedForceMode = ForceMode2D.Impulse;
protected Vector2 _force;
protected float _torque;
/// <summary>
/// On Custom Play, we apply our force or torque to the target rigidbody
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetRigidbody2D == null))
{
return;
}
switch (Mode)
{
case Modes.AddForce:
_force.x = Random.Range(MinForce.x, MaxForce.x);
_force.y = Random.Range(MinForce.y, MaxForce.y);
if (!Timing.ConstantIntensity) { _force *= feedbacksIntensity; }
TargetRigidbody2D.AddForce(_force, AppliedForceMode);
break;
case Modes.AddRelativeForce:
_force.x = Random.Range(MinForce.x, MaxForce.x);
_force.y = Random.Range(MinForce.y, MaxForce.y);
if (!Timing.ConstantIntensity) { _force *= feedbacksIntensity; }
TargetRigidbody2D.AddRelativeForce(_force, AppliedForceMode);
break;
case Modes.AddTorque:
_torque = Random.Range(MinTorque, MaxTorque);
if (!Timing.ConstantIntensity) { _torque *= feedbacksIntensity; }
TargetRigidbody2D.AddTorque(_torque, AppliedForceMode);
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f387a825823ff64cacd01b702865516
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,369 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback animates the rotation of the specified object when played
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will animate the target's rotation on the 3 specified animation curves (one per axis), for the specified duration (in seconds).")]
[FeedbackPath("Transform/Rotation")]
public class MMFeedbackRotation : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the possible modes for this feedback (Absolute : always follow the curve from start to finish, Additive : add to the values found when this feedback gets played)
public enum Modes { Absolute, Additive, ToDestination }
/// the timescale modes this feedback can operate on
public enum TimeScales { Scaled, Unscaled }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.TransformColor; } }
#endif
[Header("Rotation Target")]
/// the object whose rotation you want to animate
[Tooltip("the object whose rotation you want to animate")]
public Transform AnimateRotationTarget;
[Header("Animation")]
/// whether this feedback should animate in absolute values or additive
[Tooltip("whether this feedback should animate in absolute values or additive")]
public Modes Mode = Modes.Absolute;
/// whether this feedback should play in scaled or unscaled time
[Tooltip("whether this feedback should play in scaled or unscaled time")]
public TimeScales TimeScale = TimeScales.Scaled;
/// whether this feedback should play on local or world rotation
[Tooltip("whether this feedback should play on local or world rotation")]
public Space RotationSpace = Space.World;
/// the duration of the transition
[Tooltip("the duration of the transition")]
public float AnimateRotationDuration = 0.2f;
/// the value to remap the curve's 0 value to
[Tooltip("the value to remap the curve's 0 value to")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public float RemapCurveZero = 0f;
/// the value to remap the curve's 1 value to
[Tooltip("the value to remap the curve's 1 value to")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public float RemapCurveOne = 360f;
/// if this is true, should animate the X rotation
[Tooltip("if this is true, should animate the X rotation")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public bool AnimateX = true;
/// how the x part of the rotation should animate over time, in degrees
[Tooltip("how the x part of the rotation should animate over time, in degrees")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public AnimationCurve AnimateRotationX = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// if this is true, should animate the X rotation
[Tooltip("if this is true, should animate the X rotation")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public bool AnimateY = true;
/// how the y part of the rotation should animate over time, in degrees
[Tooltip("how the y part of the rotation should animate over time, in degrees")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public AnimationCurve AnimateRotationY = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// if this is true, should animate the X rotation
[Tooltip("if this is true, should animate the X rotation")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public bool AnimateZ = true;
/// how the z part of the rotation should animate over time, in degrees
[Tooltip("how the z part of the rotation should animate over time, in degrees")]
[MMFEnumCondition("Mode", (int)Modes.Absolute, (int)Modes.Additive)]
public AnimationCurve AnimateRotationZ = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1f), new Keyframe(1, 0));
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
/// if this is true, initial and destination rotations will be recomputed on every play
[Tooltip("if this is true, initial and destination rotations will be recomputed on every play")]
public bool DetermineRotationOnPlay = false;
[Header("To Destination")]
/// the space in which the ToDestination mode should operate
[Tooltip("the space in which the ToDestination mode should operate")]
[MMFEnumCondition("Mode", (int)Modes.ToDestination)]
public Space ToDestinationSpace = Space.World;
/// the angles to match when in ToDestination mode
[Tooltip("the angles to match when in ToDestination mode")]
[MMFEnumCondition("Mode", (int)Modes.ToDestination)]
public Vector3 DestinationAngles = new Vector3(0f, 180f, 0f);
/// the animation curve to use when animating to destination (individual x,y,z curves above won't be used)
[Tooltip("the animation curve to use when animating to destination (individual x,y,z curves above won't be used)")]
[MMFEnumCondition("Mode", (int)Modes.ToDestination)]
public AnimationCurve ToDestinationCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1f));
/// the duration of this feedback is the duration of the rotation
public override float FeedbackDuration { get { return ApplyTimeMultiplier(AnimateRotationDuration); } set { AnimateRotationDuration = value; } }
protected Quaternion _initialRotation;
protected Vector3 _initialToDestinationAngles;
protected Quaternion _destinationRotation;
protected Coroutine _coroutine;
/// <summary>
/// On init we store our initial rotation
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && (AnimateRotationTarget != null))
{
GetInitialRotation();
}
}
/// <summary>
/// Stores initial rotation for future use
/// </summary>
protected virtual void GetInitialRotation()
{
_initialRotation = (RotationSpace == Space.World) ? AnimateRotationTarget.rotation : AnimateRotationTarget.localRotation;
_initialToDestinationAngles = _initialRotation.eulerAngles;
}
/// <summary>
/// On play, we trigger our rotation animation
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (AnimateRotationTarget == null))
{
return;
}
if (DetermineRotationOnPlay && NormalPlayDirection)
{
GetInitialRotation();
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
if (isActiveAndEnabled || _hostMMFeedbacks.AutoPlayOnEnable)
{
if ((Mode == Modes.Absolute) || (Mode == Modes.Additive))
{
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(AnimateRotation(AnimateRotationTarget, Vector3.zero, FeedbackDuration, AnimateRotationX, AnimateRotationY, AnimateRotationZ, RemapCurveZero * intensityMultiplier, RemapCurveOne * intensityMultiplier));
}
else if (Mode == Modes.ToDestination)
{
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(RotateToDestination());
}
}
}
/// <summary>
/// A coroutine used to rotate the target to its destination rotation
/// </summary>
/// <returns></returns>
protected virtual IEnumerator RotateToDestination()
{
if (AnimateRotationTarget == null)
{
yield break;
}
if ((AnimateRotationX == null) || (AnimateRotationY == null) || (AnimateRotationZ == null))
{
yield break;
}
if (FeedbackDuration == 0f)
{
yield break;
}
Vector3 destinationAngles = NormalPlayDirection ? DestinationAngles : _initialToDestinationAngles;
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
_initialRotation = AnimateRotationTarget.transform.rotation;
if (ToDestinationSpace == Space.Self)
{
AnimateRotationTarget.transform.localRotation = Quaternion.Euler(destinationAngles);
}
else
{
AnimateRotationTarget.transform.rotation = Quaternion.Euler(destinationAngles);
}
_destinationRotation = AnimateRotationTarget.transform.rotation;
AnimateRotationTarget.transform.rotation = _initialRotation;
IsPlaying = true;
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float percent = Mathf.Clamp01(journey / FeedbackDuration);
percent = ToDestinationCurve.Evaluate(percent);
Quaternion newRotation = Quaternion.LerpUnclamped(_initialRotation, _destinationRotation, percent);
AnimateRotationTarget.transform.rotation = newRotation;
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
if (ToDestinationSpace == Space.Self)
{
AnimateRotationTarget.transform.localRotation = Quaternion.Euler(destinationAngles);
}
else
{
AnimateRotationTarget.transform.rotation = Quaternion.Euler(destinationAngles);
}
IsPlaying = false;
_coroutine = null;
yield break;
}
/// <summary>
/// A coroutine used to compute the rotation over time
/// </summary>
/// <param name="targetTransform"></param>
/// <param name="vector"></param>
/// <param name="duration"></param>
/// <param name="curveX"></param>
/// <param name="curveY"></param>
/// <param name="curveZ"></param>
/// <param name="multiplier"></param>
/// <returns></returns>
protected virtual IEnumerator AnimateRotation(Transform targetTransform,
Vector3 vector,
float duration,
AnimationCurve curveX,
AnimationCurve curveY,
AnimationCurve curveZ,
float remapZero,
float remapOne)
{
if (targetTransform == null)
{
yield break;
}
if ((curveX == null) || (curveY == null) || (curveZ == null))
{
yield break;
}
if (duration == 0f)
{
yield break;
}
float journey = NormalPlayDirection ? 0f : duration;
if (Mode == Modes.Additive)
{
_initialRotation = (RotationSpace == Space.World) ? targetTransform.rotation : targetTransform.localRotation;
}
IsPlaying = true;
while ((journey >= 0) && (journey <= duration) && (duration > 0))
{
float percent = Mathf.Clamp01(journey / duration);
ApplyRotation(targetTransform, remapZero, remapOne, curveX, curveY, curveZ, percent);
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
ApplyRotation(targetTransform, remapZero, remapOne, curveX, curveY, curveZ, FinalNormalizedTime);
_coroutine = null;
IsPlaying = false;
yield break;
}
/// <summary>
/// Computes and applies the rotation to the object
/// </summary>
/// <param name="targetTransform"></param>
/// <param name="multiplier"></param>
/// <param name="curveX"></param>
/// <param name="curveY"></param>
/// <param name="curveZ"></param>
/// <param name="percent"></param>
protected virtual void ApplyRotation(Transform targetTransform, float remapZero, float remapOne, AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ, float percent)
{
if (RotationSpace == Space.World)
{
targetTransform.transform.rotation = _initialRotation;
}
else
{
targetTransform.transform.localRotation = _initialRotation;
}
if (AnimateX)
{
float x = curveX.Evaluate(percent);
x = MMFeedbacksHelpers.Remap(x, 0f, 1f, remapZero, remapOne);
targetTransform.Rotate(Vector3.right, x, RotationSpace);
}
if (AnimateY)
{
float y = curveY.Evaluate(percent);
y = MMFeedbacksHelpers.Remap(y, 0f, 1f, remapZero, remapOne);
targetTransform.Rotate(Vector3.up, y, RotationSpace);
}
if (AnimateZ)
{
float z = curveZ.Evaluate(percent);
z = MMFeedbacksHelpers.Remap(z, 0f, 1f, remapZero, remapOne);
targetTransform.Rotate(Vector3.forward, z, RotationSpace);
}
}
/// <summary>
/// On stop, we interrupt movement if it was active
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (Active && FeedbackTypeAuthorized && (_coroutine != null))
{
StopCoroutine(_coroutine);
_coroutine = null;
IsPlaying = false;
}
}
/// <summary>
/// On disable we reset our coroutine
/// </summary>
protected virtual void OnDisable()
{
_coroutine = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 81d102a8ddc40ec4ba58311b11501a81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,393 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will animate the scale of the target object over time when played
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Transform/Scale")]
[FeedbackHelp("This feedback will animate the target's scale on the 3 specified animation curves, for the specified duration (in seconds). You can apply a multiplier, that will multiply each animation curve value.")]
public class MMFeedbackScale : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the possible modes this feedback can operate on
public enum Modes { Absolute, Additive, ToDestination }
/// the possible timescales for the animation of the scale
public enum TimeScales { Scaled, Unscaled }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.TransformColor; } }
#endif
[Header("Scale")]
/// the mode this feedback should operate on
/// Absolute : follows the curve
/// Additive : adds to the current scale of the target
/// ToDestination : sets the scale to the destination target, whatever the current scale is
[Tooltip("the mode this feedback should operate on" +
"Absolute : follows the curve" +
"Additive : adds to the current scale of the target" +
"ToDestination : sets the scale to the destination target, whatever the current scale is")]
public Modes Mode = Modes.Absolute;
/// whether this feedback should play in scaled or unscaled time
[Tooltip("whether this feedback should play in scaled or unscaled time")]
public TimeScales TimeScale = TimeScales.Scaled;
/// the object to animate
[Tooltip("the object to animate")]
public Transform AnimateScaleTarget;
/// the duration of the animation
[Tooltip("the duration of the animation")]
public float AnimateScaleDuration = 0.2f;
/// the value to remap the curve's 0 value to
[Tooltip("the value to remap the curve's 0 value to")]
public float RemapCurveZero = 1f;
/// the value to remap the curve's 1 value to
[Tooltip("the value to remap the curve's 1 value to")]
[FormerlySerializedAs("Multiplier")]
public float RemapCurveOne = 2f;
/// how much should be added to the curve
[Tooltip("how much should be added to the curve")]
public float Offset = 0f;
/// if this is true, should animate the X scale value
[Tooltip("if this is true, should animate the X scale value")]
public bool AnimateX = true;
/// the x scale animation definition
[Tooltip("the x scale animation definition")]
[MMFCondition("AnimateX", true)]
public AnimationCurve AnimateScaleX = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1.5f), new Keyframe(1, 0));
/// if this is true, should animate the Y scale value
[Tooltip("if this is true, should animate the Y scale value")]
public bool AnimateY = true;
/// the y scale animation definition
[Tooltip("the y scale animation definition")]
[MMFCondition("AnimateY", true)]
public AnimationCurve AnimateScaleY = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1.5f), new Keyframe(1, 0));
/// if this is true, should animate the z scale value
[Tooltip("if this is true, should animate the z scale value")]
public bool AnimateZ = true;
/// the z scale animation definition
[Tooltip("the z scale animation definition")]
[MMFCondition("AnimateZ", true)]
public AnimationCurve AnimateScaleZ = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1.5f), new Keyframe(1, 0));
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
/// if this is true, initial and destination scales will be recomputed on every play
[Tooltip("if this is true, initial and destination scales will be recomputed on every play")]
public bool DetermineScaleOnPlay = false;
[Header("To Destination")]
/// the scale to reach when in ToDestination mode
[Tooltip("the scale to reach when in ToDestination mode")]
[MMFEnumCondition("Mode", (int)Modes.ToDestination)]
public Vector3 DestinationScale = new Vector3(0.5f, 0.5f, 0.5f);
/// the duration of this feedback is the duration of the scale animation
public override float FeedbackDuration { get { return ApplyTimeMultiplier(AnimateScaleDuration); } set { AnimateScaleDuration = value; } }
protected Vector3 _initialScale;
protected Vector3 _newScale;
protected Coroutine _coroutine;
/// <summary>
/// On init we store our initial scale
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && (AnimateScaleTarget != null))
{
GetInitialScale();
}
}
/// <summary>
/// Stores initial scale for future use
/// </summary>
protected virtual void GetInitialScale()
{
_initialScale = AnimateScaleTarget.localScale;
}
/// <summary>
/// On Play, triggers the scale animation
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (AnimateScaleTarget == null))
{
return;
}
if (DetermineScaleOnPlay && NormalPlayDirection)
{
GetInitialScale();
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
if (isActiveAndEnabled || _hostMMFeedbacks.AutoPlayOnEnable)
{
if ((Mode == Modes.Absolute) || (Mode == Modes.Additive))
{
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(AnimateScale(AnimateScaleTarget, Vector3.zero, FeedbackDuration, AnimateScaleX, AnimateScaleY, AnimateScaleZ, RemapCurveZero * intensityMultiplier, RemapCurveOne * intensityMultiplier));
}
if (Mode == Modes.ToDestination)
{
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(ScaleToDestination());
}
}
}
/// <summary>
/// An internal coroutine used to scale the target to its destination scale
/// </summary>
/// <returns></returns>
protected virtual IEnumerator ScaleToDestination()
{
if (AnimateScaleTarget == null)
{
yield break;
}
if ((AnimateScaleX == null) || (AnimateScaleY == null) || (AnimateScaleZ == null))
{
yield break;
}
if (FeedbackDuration == 0f)
{
yield break;
}
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
_initialScale = AnimateScaleTarget.localScale;
_newScale = _initialScale;
IsPlaying = true;
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float percent = Mathf.Clamp01(journey / FeedbackDuration);
if (AnimateX)
{
_newScale.x = Mathf.LerpUnclamped(_initialScale.x, DestinationScale.x, AnimateScaleX.Evaluate(percent) + Offset);
_newScale.x = MMFeedbacksHelpers.Remap(_newScale.x, 0f, 1f, RemapCurveZero, RemapCurveOne);
}
if (AnimateY)
{
_newScale.y = Mathf.LerpUnclamped(_initialScale.y, DestinationScale.y, AnimateScaleY.Evaluate(percent) + Offset);
_newScale.y = MMFeedbacksHelpers.Remap(_newScale.y, 0f, 1f, RemapCurveZero, RemapCurveOne);
}
if (AnimateZ)
{
_newScale.z = Mathf.LerpUnclamped(_initialScale.z, DestinationScale.z, AnimateScaleZ.Evaluate(percent) + Offset);
_newScale.z = MMFeedbacksHelpers.Remap(_newScale.z, 0f, 1f, RemapCurveZero, RemapCurveOne);
}
AnimateScaleTarget.localScale = _newScale;
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
AnimateScaleTarget.localScale = NormalPlayDirection ? DestinationScale : _initialScale;
_coroutine = null;
IsPlaying = false;
yield return null;
}
/// <summary>
/// An internal coroutine used to animate the scale over time
/// </summary>
/// <param name="targetTransform"></param>
/// <param name="vector"></param>
/// <param name="duration"></param>
/// <param name="curveX"></param>
/// <param name="curveY"></param>
/// <param name="curveZ"></param>
/// <param name="multiplier"></param>
/// <returns></returns>
protected virtual IEnumerator AnimateScale(Transform targetTransform, Vector3 vector, float duration, AnimationCurve curveX, AnimationCurve curveY, AnimationCurve curveZ, float remapCurveZero = 0f, float remapCurveOne = 1f)
{
if (targetTransform == null)
{
yield break;
}
if ((curveX == null) || (curveY == null) || (curveZ == null))
{
yield break;
}
if (duration == 0f)
{
yield break;
}
float journey = NormalPlayDirection ? 0f : duration;
_initialScale = targetTransform.localScale;
IsPlaying = true;
while ((journey >= 0) && (journey <= duration) && (duration > 0))
{
vector = Vector3.zero;
float percent = Mathf.Clamp01(journey / duration);
if (AnimateX)
{
vector.x = AnimateX ? curveX.Evaluate(percent) + Offset : targetTransform.localScale.x;
vector.x = MMFeedbacksHelpers.Remap(vector.x, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
vector.x += _initialScale.x;
}
}
else
{
vector.x = targetTransform.localScale.x;
}
if (AnimateY)
{
vector.y = AnimateY ? curveY.Evaluate(percent) + Offset : targetTransform.localScale.y;
vector.y = MMFeedbacksHelpers.Remap(vector.y, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
vector.y += _initialScale.y;
}
}
else
{
vector.y = targetTransform.localScale.y;
}
if (AnimateZ)
{
vector.z = AnimateZ ? curveZ.Evaluate(percent) + Offset : targetTransform.localScale.z;
vector.z = MMFeedbacksHelpers.Remap(vector.z, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
vector.z += _initialScale.z;
}
}
else
{
vector.z = targetTransform.localScale.z;
}
targetTransform.localScale = vector;
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
vector = Vector3.zero;
if (AnimateX)
{
vector.x = AnimateX ? curveX.Evaluate(FinalNormalizedTime) + Offset : targetTransform.localScale.x;
vector.x = MMFeedbacksHelpers.Remap(vector.x, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
vector.x += _initialScale.x;
}
}
else
{
vector.x = targetTransform.localScale.x;
}
if (AnimateY)
{
vector.y = AnimateY ? curveY.Evaluate(FinalNormalizedTime) + Offset : targetTransform.localScale.y;
vector.y = MMFeedbacksHelpers.Remap(vector.y, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
vector.y += _initialScale.y;
}
}
else
{
vector.y = targetTransform.localScale.y;
}
if (AnimateZ)
{
vector.z = AnimateZ ? curveZ.Evaluate(FinalNormalizedTime) + Offset : targetTransform.localScale.z;
vector.z = MMFeedbacksHelpers.Remap(vector.z, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
vector.z += _initialScale.z;
}
}
else
{
vector.z = targetTransform.localScale.z;
}
targetTransform.localScale = vector;
_coroutine = null;
IsPlaying = false;
yield return null;
}
/// <summary>
/// On stop, we interrupt movement if it was active
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (_coroutine == null))
{
return;
}
StopCoroutine(_coroutine);
IsPlaying = false;
_coroutine = null;
}
/// <summary>
/// On disable we reset our coroutine
/// </summary>
protected virtual void OnDisable()
{
_coroutine = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d958a52145b19904aa2a5bcb3849eafb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,155 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// Turns an object active or inactive at the various stages of the feedback
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to change the state of the target gameobject from active to inactive (or the opposite), on init, play, stop or reset. For each of these you can specify if you want to force a state (active or inactive), or toggle it (active becomes inactive, inactive becomes active).")]
[FeedbackPath("GameObject/Set Active")]
public class MMFeedbackSetActive : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.GameObjectColor; } }
#endif
/// the possible effects the feedback can have on the target object's status
public enum PossibleStates { Active, Inactive, Toggle }
[Header("Set Active")]
/// the gameobject we want to change the active state of
[Tooltip("the gameobject we want to change the active state of")]
public GameObject TargetGameObject;
[Header("States")]
/// whether or not we should alter the state of the target object on init
[Tooltip("whether or not we should alter the state of the target object on init")]
public bool SetStateOnInit = false;
[MMFCondition("SetStateOnInit", true)]
/// how to change the state on init
[Tooltip("how to change the state on init")]
public PossibleStates StateOnInit = PossibleStates.Inactive;
/// whether or not we should alter the state of the target object on play
[Tooltip("whether or not we should alter the state of the target object on play")]
public bool SetStateOnPlay = false;
/// how to change the state on play
[Tooltip("how to change the state on play")]
[MMFCondition("SetStateOnPlay", true)]
public PossibleStates StateOnPlay = PossibleStates.Inactive;
/// whether or not we should alter the state of the target object on stop
[Tooltip("whether or not we should alter the state of the target object on stop")]
public bool SetStateOnStop = false;
/// how to change the state on stop
[Tooltip("how to change the state on stop")]
[MMFCondition("SetStateOnStop", true)]
public PossibleStates StateOnStop = PossibleStates.Inactive;
/// whether or not we should alter the state of the target object on reset
[Tooltip("whether or not we should alter the state of the target object on reset")]
public bool SetStateOnReset = false;
/// how to change the state on reset
[Tooltip("how to change the state on reset")]
[MMFCondition("SetStateOnReset", true)]
public PossibleStates StateOnReset = PossibleStates.Inactive;
/// <summary>
/// On init we change the state of our object if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && (TargetGameObject != null))
{
if (SetStateOnInit)
{
SetStatus(StateOnInit);
}
}
}
/// <summary>
/// On Play we change the state of our object if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (TargetGameObject == null))
{
return;
}
if (SetStateOnPlay)
{
SetStatus(StateOnPlay);
}
}
/// <summary>
/// On Stop we change the state of our object if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
base.CustomStopFeedback(position, feedbacksIntensity);
if (Active && FeedbackTypeAuthorized && (TargetGameObject != null))
{
if (SetStateOnStop)
{
SetStatus(StateOnStop);
}
}
}
/// <summary>
/// On Reset we change the state of our object if needed
/// </summary>
protected override void CustomReset()
{
base.CustomReset();
if (InCooldown)
{
return;
}
if (Active && FeedbackTypeAuthorized && (TargetGameObject != null))
{
if (SetStateOnReset)
{
SetStatus(StateOnReset);
}
}
}
/// <summary>
/// Changes the status of the object
/// </summary>
/// <param name="state"></param>
protected virtual void SetStatus(PossibleStates state)
{
bool newState = false;
switch (state)
{
case PossibleStates.Active:
newState = NormalPlayDirection ? true : false;
break;
case PossibleStates.Inactive:
newState = NormalPlayDirection ? false : true;
break;
case PossibleStates.Toggle:
newState = !TargetGameObject.activeInHierarchy;
break;
}
TargetGameObject.SetActive(newState);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f129222f02399ae42b78955d953ada11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,152 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// Turns an object active or inactive at the various stages of the feedback
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback allows you to set global properties on your shader, or enable/disable keywords.")]
[FeedbackPath("Renderer/Shader Global")]
public class MMFeedbackShaderGlobal : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.RendererColor; } }
#endif
public enum Modes { SetGlobalColor, SetGlobalFloat, SetGlobalInt, SetGlobalMatrix, SetGlobalTexture, SetGlobalVector, EnableKeyword, DisableKeyword, WarmupAllShaders }
[Header("Shader Global")]
public Modes Mode = Modes.SetGlobalFloat;
/// the name of the global property
[Tooltip("the name of the global property")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalColor, (int)Modes.SetGlobalFloat, (int)Modes.SetGlobalInt, (int)Modes.SetGlobalMatrix, (int)Modes.SetGlobalTexture, (int)Modes.SetGlobalVector)]
public string PropertyName = "";
/// the name ID of the property retrieved by Shader.PropertyToID
[Tooltip("the name ID of the property retrieved by Shader.PropertyToID")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalColor, (int)Modes.SetGlobalFloat, (int)Modes.SetGlobalInt, (int)Modes.SetGlobalMatrix, (int)Modes.SetGlobalTexture, (int)Modes.SetGlobalVector)]
public int PropertyNameID = 0;
/// a global color property for all shaders
[Tooltip("a global color property for all shaders")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalColor)]
public Color GlobalColor = Color.yellow;
/// a global float property for all shaders
[Tooltip("a global float property for all shaders")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalFloat)]
public float GlobalFloat = 1f;
/// a global int property for all shaders
[Tooltip("a global int property for all shaders")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalInt)]
public int GlobalInt = 1;
/// a global matrix property for all shaders
[Tooltip("a global matrix property for all shaders")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalMatrix)]
public Matrix4x4 GlobalMatrix = Matrix4x4.identity;
/// a global texture property for all shaders
[Tooltip("a global texture property for all shaders")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalTexture)]
public RenderTexture GlobalTexture;
/// a global vector property for all shaders
[Tooltip("a global vector property for all shaders")]
[MMFEnumCondition("Mode", (int)Modes.SetGlobalVector)]
public Vector4 GlobalVector;
/// a global shader keyword
[Tooltip("a global shader keyword")]
[MMFEnumCondition("Mode", (int)Modes.EnableKeyword, (int)Modes.DisableKeyword)]
public string Keyword;
/// <summary>
/// On Play we set our global shader property
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
switch (Mode)
{
case Modes.SetGlobalColor:
if (PropertyName == "")
{
Shader.SetGlobalColor(PropertyNameID, GlobalColor);
}
else
{
Shader.SetGlobalColor(PropertyName, GlobalColor);
}
break;
case Modes.SetGlobalFloat:
if (PropertyName == "")
{
Shader.SetGlobalFloat(PropertyNameID, GlobalFloat);
}
else
{
Shader.SetGlobalFloat(PropertyName, GlobalFloat);
}
break;
case Modes.SetGlobalInt:
if (PropertyName == "")
{
Shader.SetGlobalInt(PropertyNameID, GlobalInt);
}
else
{
Shader.SetGlobalInt(PropertyName, GlobalInt);
}
break;
case Modes.SetGlobalMatrix:
if (PropertyName == "")
{
Shader.SetGlobalMatrix(PropertyNameID, GlobalMatrix);
}
else
{
Shader.SetGlobalMatrix(PropertyName, GlobalMatrix);
}
break;
case Modes.SetGlobalTexture:
if (PropertyName == "")
{
Shader.SetGlobalTexture(PropertyNameID, GlobalTexture);
}
else
{
Shader.SetGlobalTexture(PropertyName, GlobalTexture);
}
break;
case Modes.SetGlobalVector:
if (PropertyName == "")
{
Shader.SetGlobalVector(PropertyNameID, GlobalVector);
}
else
{
Shader.SetGlobalVector(PropertyName, GlobalVector);
}
break;
case Modes.EnableKeyword:
Shader.EnableKeyword(Keyword);
break;
case Modes.DisableKeyword:
Shader.DisableKeyword(Keyword);
break;
case Modes.WarmupAllShaders:
Shader.WarmupAllShaders();
break;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d90bef4fb7967b4cbc390913de85cc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you change the scene's skybox on play, replacing it with another one, either a specific one, or one picked at random among multiple skyboxes.
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you change the scene's skybox on play, replacing it with another one, either a specific one, or one picked at random among multiple skyboxes.")]
[FeedbackPath("Renderer/Skybox")]
public class MMFeedbackSkybox : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.RendererColor; } }
#endif
/// whether skyboxes are selected at random or not
public enum Modes { Single, Random }
[Header("Skybox")]
/// the selected mode
public Modes Mode = Modes.Single;
/// the skybox to assign when in Single mode
public Material SingleSkybox;
/// the skyboxes to pick from when in Random mode
public Material[] RandomSkyboxes;
/// <summary>
/// On play, we set the scene's skybox to a new one
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (Mode == Modes.Single)
{
RenderSettings.skybox = SingleSkybox;
}
else if (Mode == Modes.Random)
{
RenderSettings.skybox = RandomSkyboxes[Random.Range(0, RandomSkyboxes.Length)];
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6041c1460787d0249933562772a18603
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,329 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you change the color of a target sprite renderer over time, and flip it on X or Y. You can also use it to command one or many MMSpriteRendererShakers.
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback will let you change the color of a target sprite renderer over time, and flip it on X or Y. You can also use it to command one or many MMSpriteRendererShakers.")]
[FeedbackPath("Renderer/SpriteRenderer")]
public class MMFeedbackSpriteRenderer : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.RendererColor; } }
#endif
/// the possible modes for this feedback
public enum Modes { OverTime, Instant, ShakerEvent, ToDestinationColor, ToDestinationColorAndBack }
/// the different ways to grab initial color
public enum InitialColorModes { InitialColorOnInit, InitialColorOnPlay }
[Header("Sprite Renderer")]
/// the SpriteRenderer to affect when playing the feedback
[Tooltip("the SpriteRenderer to affect when playing the feedback")]
public SpriteRenderer BoundSpriteRenderer;
/// whether the feedback should affect the sprite renderer instantly or over a period of time
[Tooltip("whether the feedback should affect the sprite renderer instantly or over a period of time")]
public Modes Mode = Modes.OverTime;
/// how long the sprite renderer should change over time
[Tooltip("how long the sprite renderer should change over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent, (int)Modes.ToDestinationColor, (int)Modes.ToDestinationColorAndBack)]
public float Duration = 0.2f;
/// whether or not that sprite renderer should be turned off on start
[Tooltip("whether or not that sprite renderer should be turned off on start")]
public bool StartsOff = false;
/// the channel to broadcast on
[Tooltip("the channel to broadcast on")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public int Channel = 0;
/// whether or not to reset shaker values after shake
[Tooltip("whether or not to reset shaker values after shake")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool ResetShakerValuesAfterShake = true;
/// whether or not to reset the target's values after shake
[Tooltip("whether or not to reset the target's values after shake")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool ResetTargetValuesAfterShake = true;
/// whether or not to broadcast a range to only affect certain shakers
[Tooltip("whether or not to broadcast a range to only affect certain shakers")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public bool UseRange = false;
/// the range of the event, in units
[Tooltip("the range of the event, in units")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public float EventRange = 100f;
/// the transform to use to broadcast the event as origin point
[Tooltip("the transform to use to broadcast the event as origin point")]
[MMFEnumCondition("Mode", (int)Modes.ShakerEvent)]
public Transform EventOriginTransform;
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
/// whether to grab the initial color to (potentially) go back to at init or when the feedback plays
[Tooltip("whether to grab the initial color to (potentially) go back to at init or when the feedback plays")]
public InitialColorModes InitialColorMode = InitialColorModes.InitialColorOnPlay;
[Header("Color")]
/// whether or not to modify the color of the sprite renderer
[Tooltip("whether or not to modify the color of the sprite renderer")]
public bool ModifyColor = true;
/// the colors to apply to the sprite renderer over time
[Tooltip("the colors to apply to the sprite renderer over time")]
[MMFEnumCondition("Mode", (int)Modes.OverTime, (int)Modes.ShakerEvent)]
public Gradient ColorOverTime;
/// the color to move to in instant mode
[Tooltip("the color to move to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant, (int)Modes.ShakerEvent)]
public Color InstantColor;
/// the color to move to in ToDestination mode
[Tooltip("the color to move to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant, (int)Modes.ToDestinationColor, (int)Modes.ToDestinationColorAndBack)]
public Color ToDestinationColor = Color.red;
/// the color to move to in ToDestination mode
[Tooltip("the color to move to in instant mode")]
[MMFEnumCondition("Mode", (int)Modes.Instant, (int)Modes.ToDestinationColor, (int)Modes.ToDestinationColorAndBack)]
public AnimationCurve ToDestinationColorCurve = new AnimationCurve(new Keyframe(0, 0f), new Keyframe(1, 1f));
[Header("Flip")]
/// whether or not to flip the sprite on X
[Tooltip("whether or not to flip the sprite on X")]
public bool FlipX = false;
/// whether or not to flip the sprite on Y
[Tooltip("whether or not to flip the sprite on Y")]
public bool FlipY = false;
/// the duration of this feedback is the duration of the sprite renderer, or 0 if instant
public override float FeedbackDuration { get { return (Mode == Modes.Instant) ? 0f : ApplyTimeMultiplier(Duration); } set { Duration = value; } }
protected Coroutine _coroutine;
protected Color _initialColor;
/// <summary>
/// On init we turn the sprite renderer off if needed
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (EventOriginTransform == null)
{
EventOriginTransform = this.transform;
}
if (Active)
{
if (StartsOff)
{
Turn(false);
}
}
if ((BoundSpriteRenderer != null) && (InitialColorMode == InitialColorModes.InitialColorOnInit))
{
_initialColor = BoundSpriteRenderer.color;
}
}
/// <summary>
/// On Play we turn our sprite renderer on and start an over time coroutine if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if ((BoundSpriteRenderer != null) && (InitialColorMode == InitialColorModes.InitialColorOnPlay))
{
_initialColor = BoundSpriteRenderer.color;
}
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
Turn(true);
switch (Mode)
{
case Modes.Instant:
if (ModifyColor)
{
BoundSpriteRenderer.color = InstantColor;
}
Flip();
break;
case Modes.OverTime:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(SpriteRendererSequence());
break;
case Modes.ShakerEvent:
MMSpriteRendererShakeEvent.Trigger(FeedbackDuration, ModifyColor, ColorOverTime,
FlipX, FlipY,
intensityMultiplier,
ChannelData(Channel), ResetShakerValuesAfterShake, ResetTargetValuesAfterShake,
UseRange, EventRange, EventOriginTransform.position);
break;
case Modes.ToDestinationColor:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(SpriteRendererToDestinationSequence(false));
break;
case Modes.ToDestinationColorAndBack:
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(SpriteRendererToDestinationSequence(true));
break;
}
}
/// <summary>
/// This coroutine will modify the values on the SpriteRenderer
/// </summary>
/// <returns></returns>
protected virtual IEnumerator SpriteRendererSequence()
{
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
IsPlaying = true;
Flip();
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float remappedTime = MMFeedbacksHelpers.Remap(journey, 0f, FeedbackDuration, 0f, 1f);
SetSpriteRendererValues(remappedTime);
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
yield return null;
}
SetSpriteRendererValues(FinalNormalizedTime);
if (StartsOff)
{
Turn(false);
}
_coroutine = null;
IsPlaying = false;
yield return null;
}
/// <summary>
/// This coroutine will modify the values on the SpriteRenderer
/// </summary>
/// <returns></returns>
protected virtual IEnumerator SpriteRendererToDestinationSequence(bool andBack)
{
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
IsPlaying = true;
Flip();
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float remappedTime = MMFeedbacksHelpers.Remap(journey, 0f, FeedbackDuration, 0f, 1f);
if (andBack)
{
remappedTime = (remappedTime < 0.5f)
? MMFeedbacksHelpers.Remap(remappedTime, 0f, 0.5f, 0f, 1f)
: MMFeedbacksHelpers.Remap(remappedTime, 0.5f, 1f, 1f, 0f);
}
float evalTime = ToDestinationColorCurve.Evaluate(remappedTime);
if (ModifyColor)
{
BoundSpriteRenderer.color = Color.LerpUnclamped(_initialColor, ToDestinationColor, evalTime);
}
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
yield return null;
}
if (ModifyColor)
{
BoundSpriteRenderer.color = andBack ? _initialColor : ToDestinationColor;
}
if (StartsOff)
{
Turn(false);
}
_coroutine = null;
IsPlaying = false;
yield return null;
}
/// <summary>
/// Flips the sprite on X or Y based on the FlipX/FlipY settings
/// </summary>
protected virtual void Flip()
{
if (FlipX)
{
BoundSpriteRenderer.flipX = !BoundSpriteRenderer.flipX;
}
if (FlipY)
{
BoundSpriteRenderer.flipY = !BoundSpriteRenderer.flipY;
}
}
/// <summary>
/// Sets the various values on the sprite renderer on a specified time (between 0 and 1)
/// </summary>
/// <param name="time"></param>
protected virtual void SetSpriteRendererValues(float time)
{
if (ModifyColor)
{
BoundSpriteRenderer.color = ColorOverTime.Evaluate(time);
}
}
/// <summary>
/// Stops the transition on stop if needed
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
{
if (!Active || !FeedbackTypeAuthorized || (_coroutine == null))
{
return;
}
base.CustomStopFeedback(position, feedbacksIntensity);
StopCoroutine(_coroutine);
IsPlaying = false;
_coroutine = null;
}
/// <summary>
/// Turns the sprite renderer on or off
/// </summary>
/// <param name="status"></param>
protected virtual void Turn(bool status)
{
BoundSpriteRenderer.gameObject.SetActive(status);
BoundSpriteRenderer.enabled = status;
}
/// <summary>
/// On disable,
/// </summary>
protected virtual void OnDisable()
{
_coroutine = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0598124d440bea94aaf85767e74a38b2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,386 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Serialization;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback will let you modify the scale of an object on an axis while the other two axis (or only one) get automatically modified to conserve mass
/// </summary>
[AddComponentMenu("")]
[FeedbackPath("Transform/Squash and Stretch")]
[FeedbackHelp("This feedback will let you modify the scale of an object on an axis while the other two axis (or only one) get automatically modified to conserve mass.")]
public class MMFeedbackSquashAndStretch : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
/// the possible modes this feedback can operate on
public enum Modes { Absolute, Additive, ToDestination }
/// the various axis on which to apply the squash and stretch
public enum PossibleAxis { XtoYZ, XtoY, XtoZ, YtoXZ, YtoX, YtoZ, ZtoXZ, ZtoX, ZtoY }
/// the possible timescales for the animation of the scale
public enum TimeScales { Scaled, Unscaled }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.TransformColor; } }
#endif
[Header("Squash & Stretch")]
/// the object to animate
[Tooltip("the object to animate")]
public Transform SquashAndStretchTarget;
/// the mode this feedback should operate on
/// Absolute : follows the curve
/// Additive : adds to the current scale of the target
/// ToDestination : sets the scale to the destination target, whatever the current scale is
[Tooltip("the mode this feedback should operate on" +
"Absolute : follows the curve" +
"Additive : adds to the current scale of the target" +
"ToDestination : sets the scale to the destination target, whatever the current scale is")]
public Modes Mode = Modes.Absolute;
public PossibleAxis Axis = PossibleAxis.YtoXZ;
/// whether this feedback should play in scaled or unscaled time
[Tooltip("whether this feedback should play in scaled or unscaled time")]
public TimeScales TimeScale = TimeScales.Scaled;
/// the duration of the animation
[Tooltip("the duration of the animation")]
public float AnimateScaleDuration = 0.2f;
/// the value to remap the curve's 0 value to
[Tooltip("the value to remap the curve's 0 value to")]
public float RemapCurveZero = 1f;
/// the value to remap the curve's 1 value to
[Tooltip("the value to remap the curve's 1 value to")]
[FormerlySerializedAs("Multiplier")]
public float RemapCurveOne = 2f;
/// how much should be added to the curve
[Tooltip("how much should be added to the curve")]
public float Offset = 0f;
/// the curve along which to animate the scale
[Tooltip("the curve along which to animate the scale")]
public AnimationCurve AnimateCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.3f, 1.5f), new Keyframe(1, 0));
/// if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over
[Tooltip("if this is true, calling that feedback will trigger it, even if it's in progress. If it's false, it'll prevent any new Play until the current one is over")]
public bool AllowAdditivePlays = false;
/// if this is true, initial and destination scales will be recomputed on every play
[Tooltip("if this is true, initial and destination scales will be recomputed on every play")]
public bool DetermineScaleOnPlay = false;
[Header("To Destination")]
/// the scale to reach when in ToDestination mode
[Tooltip("the scale to reach when in ToDestination mode")]
[MMFEnumCondition("Mode", (int)Modes.ToDestination)]
public float DestinationScale = 2f;
/// the duration of this feedback is the duration of the scale animation
public override float FeedbackDuration { get { return ApplyTimeMultiplier(AnimateScaleDuration); } set { AnimateScaleDuration = value; } }
protected Vector3 _initialScale;
protected float _initialAxisScale;
protected Vector3 _newScale;
protected Coroutine _coroutine;
/// <summary>
/// On init we store our initial scale
/// </summary>
/// <param name="owner"></param>
protected override void CustomInitialization(GameObject owner)
{
base.CustomInitialization(owner);
if (Active && (SquashAndStretchTarget != null))
{
GetInitialScale();
}
}
/// <summary>
/// Stores initial scale for future use
/// </summary>
protected virtual void GetInitialScale()
{
_initialScale = SquashAndStretchTarget.localScale;
}
protected virtual void GetAxisScale()
{
switch (Axis)
{
case PossibleAxis.XtoYZ:
_initialAxisScale = SquashAndStretchTarget.localScale.x;
break;
case PossibleAxis.XtoY:
_initialAxisScale = SquashAndStretchTarget.localScale.x;
break;
case PossibleAxis.XtoZ:
_initialAxisScale = SquashAndStretchTarget.localScale.x;
break;
case PossibleAxis.YtoXZ:
_initialAxisScale = SquashAndStretchTarget.localScale.y;
break;
case PossibleAxis.YtoX:
_initialAxisScale = SquashAndStretchTarget.localScale.y;
break;
case PossibleAxis.YtoZ:
_initialAxisScale = SquashAndStretchTarget.localScale.y;
break;
case PossibleAxis.ZtoXZ:
_initialAxisScale = SquashAndStretchTarget.localScale.z;
break;
case PossibleAxis.ZtoX:
_initialAxisScale = SquashAndStretchTarget.localScale.z;
break;
case PossibleAxis.ZtoY:
_initialAxisScale = SquashAndStretchTarget.localScale.z;
break;
}
}
/// <summary>
/// On Play, triggers the scale animation
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized || (SquashAndStretchTarget == null))
{
return;
}
if (DetermineScaleOnPlay && NormalPlayDirection)
{
GetInitialScale();
}
GetAxisScale();
float intensityMultiplier = Timing.ConstantIntensity ? 1f : feedbacksIntensity;
if (isActiveAndEnabled || _hostMMFeedbacks.AutoPlayOnEnable)
{
if ((Mode == Modes.Absolute) || (Mode == Modes.Additive))
{
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(AnimateScale(SquashAndStretchTarget, FeedbackDuration, AnimateCurve, Axis, RemapCurveZero * intensityMultiplier, RemapCurveOne * intensityMultiplier));
}
if (Mode == Modes.ToDestination)
{
if (!AllowAdditivePlays && (_coroutine != null))
{
return;
}
_coroutine = StartCoroutine(ScaleToDestination());
}
}
}
/// <summary>
/// An internal coroutine used to scale the target to its destination scale
/// </summary>
/// <returns></returns>
protected virtual IEnumerator ScaleToDestination()
{
if (SquashAndStretchTarget == null)
{
yield break;
}
if (FeedbackDuration == 0f)
{
yield break;
}
float journey = NormalPlayDirection ? 0f : FeedbackDuration;
_initialScale = SquashAndStretchTarget.localScale;
_newScale = _initialScale;
GetAxisScale();
IsPlaying = true;
while ((journey >= 0) && (journey <= FeedbackDuration) && (FeedbackDuration > 0))
{
float percent = Mathf.Clamp01(journey / FeedbackDuration);
float newScale = Mathf.LerpUnclamped(_initialAxisScale, DestinationScale, AnimateCurve.Evaluate(percent) + Offset);
newScale = MMFeedbacksHelpers.Remap(newScale, 0f, 1f, RemapCurveZero, RemapCurveOne);
ApplyScale(newScale);
SquashAndStretchTarget.localScale = _newScale;
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
ApplyScale(DestinationScale);
SquashAndStretchTarget.localScale = NormalPlayDirection ? _newScale : _initialScale;
_coroutine = null;
IsPlaying = false;
yield return null;
}
/// <summary>
/// An internal coroutine used to animate the scale over time
/// </summary>
/// <param name="targetTransform"></param>
/// <param name="duration"></param>
/// <param name="curveX"></param>
/// <param name="curveY"></param>
/// <param name="curveZ"></param>
/// <param name="multiplier"></param>
/// <returns></returns>
protected virtual IEnumerator AnimateScale(Transform targetTransform, float duration, AnimationCurve curve, PossibleAxis axis, float remapCurveZero = 0f, float remapCurveOne = 1f)
{
if (targetTransform == null)
{
yield break;
}
if (duration == 0f)
{
yield break;
}
float journey = NormalPlayDirection ? 0f : duration;
_initialScale = targetTransform.localScale;
IsPlaying = true;
while ((journey >= 0) && (journey <= duration) && (duration > 0))
{
float percent = Mathf.Clamp01(journey / duration);
float newScale = curve.Evaluate(percent) + Offset;
newScale = MMFeedbacksHelpers.Remap(newScale, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
newScale += _initialAxisScale;
}
ApplyScale(newScale);
targetTransform.localScale = _newScale;
if (TimeScale == TimeScales.Scaled)
{
journey += NormalPlayDirection ? FeedbackDeltaTime : -FeedbackDeltaTime;
}
else
{
journey += NormalPlayDirection ? Time.unscaledDeltaTime : -Time.unscaledDeltaTime;
}
yield return null;
}
float finalScale;
finalScale = curve.Evaluate(FinalNormalizedTime) + Offset;
finalScale = MMFeedbacksHelpers.Remap(finalScale, 0f, 1f, remapCurveZero, remapCurveOne);
if (Mode == Modes.Additive)
{
finalScale += _initialAxisScale;
}
ApplyScale(finalScale);
targetTransform.localScale = _newScale;
_coroutine = null;
IsPlaying = false;
yield return null;
}
/// <summary>
/// Applies the new scale on the selected axis
/// </summary>
/// <param name="newScale"></param>
protected virtual void ApplyScale(float newScale)
{
float invertScale = 1 / Mathf.Sqrt(newScale);
switch (Axis)
{
case PossibleAxis.XtoYZ:
_newScale.x = newScale;
_newScale.y = invertScale;
_newScale.z = invertScale;
break;
case PossibleAxis.XtoY:
_newScale.x = newScale;
_newScale.y = invertScale;
_newScale.z = _initialScale.z;
break;
case PossibleAxis.XtoZ:
_newScale.x = newScale;
_newScale.y = _initialScale.y;
_newScale.z = invertScale;
break;
case PossibleAxis.YtoXZ:
_newScale.x = invertScale;
_newScale.y = newScale;
_newScale.z = invertScale;
break;
case PossibleAxis.YtoX:
_newScale.x = invertScale;
_newScale.y = newScale;
_newScale.z = _initialScale.z;
break;
case PossibleAxis.YtoZ:
_newScale.x = newScale;
_newScale.y = _initialScale.y;
_newScale.z = invertScale;
break;
case PossibleAxis.ZtoXZ:
_newScale.x = invertScale;
_newScale.y = invertScale;
_newScale.z = newScale;
break;
case PossibleAxis.ZtoX:
_newScale.x = invertScale;
_newScale.y = _initialScale.y;
_newScale.z = newScale;
break;
case PossibleAxis.ZtoY:
_newScale.x = _initialScale.x;
_newScale.y = invertScale;
_newScale.z = newScale;
break;
}
}
/// <summary>
/// On stop, we interrupt movement if it was active
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (Active && (_coroutine != null))
{
StopCoroutine(_coroutine);
_coroutine = null;
IsPlaying = false;
}
}
/// <summary>
/// On disable we reset our coroutine
/// </summary>
protected virtual void OnDisable()
{
_coroutine = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d803dc7f93e946243abbbce0cfd3534f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
namespace MoreMountains.Feedbacks
{
/// <summary>
/// This feedback lets you control the contents of a target Text over time
/// </summary>
[AddComponentMenu("")]
[FeedbackHelp("This feedback lets you control the contents of a target Text over time.")]
[FeedbackPath("UI/Text")]
public class MMFeedbackText : MMFeedback
{
/// a static bool used to disable all feedbacks of this type at once
public static bool FeedbackTypeAuthorized = true;
public enum ColorModes { Instant, Gradient, Interpolate }
/// sets the inspector color for this feedback
#if UNITY_EDITOR
public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.UIColor; } }
#endif
[Header("Target")]
/// the Text component to control
[Tooltip(" Text component to control")]
public Text TargetText;
/// the new text to replace the old one with
[Tooltip("the new text to replace the old one with")]
[TextArea]
public string NewText = "Hello World";
/// <summary>
/// On play we change the text of our target TMPText
/// </summary>
/// <param name="position"></param>
/// <param name="feedbacksIntensity"></param>
protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
{
if (!Active || !FeedbackTypeAuthorized)
{
return;
}
if (TargetText == null)
{
return;
}
TargetText.text = NewText;
}
}
}

Some files were not shown because too many files have changed in this diff Show More