This section explains all there is to know to create a new MMFeedback.

Creating a new feedback

Creating a new feedback is very easy. Create a new class, have it inherit from MMFeedback, and override the methods you’re interested in (usually CustomInitialization, CustomPlayFeedback, CustomStopFeedback and CustomReset). You can look at each feedback for a reference of how it’s done, they’re all heavily commented. Here’s a template you can use as a starting point :

using UnityEngine;
using MoreMountains.Feedbacks;

[AddComponentMenu("")]
[FeedbackPath("ChosenPath/MyFeedbackNameGoesHere")]
public class MMFeedbackMyFeedbackNameGoesHere : MMFeedback
{
    // declare your variables here

    protected override void CustomInitialization(GameObject owner)
    {
        base.CustomInitialization(owner);
        if (Active)
        {
            // Put custom initialization code here
        }
    }

    protected override void CustomPlayFeedback(Vector3 position, float attenuation = 1.0f)
    {
        if (Active)
        {
            // Put custom play code here
        }
    }

    protected override void CustomStopFeedback(Vector3 position, float attenuation = 1)
    {
        base.CustomStopFeedback(position, attenuation);
        if (Active)
        {
            // Put custom stop code here
        }
    }

    protected override void CustomReset()
    {
        base.CustomReset();
        if (Active)
        {
            // Put custom reset code here
        }
    }
}


The MMFeedbackBase class

MMFeedbacks come with a base class you can extend if your use case applies. That abstract class is designed to handle cases where your feedback is meant to modify one or more values (float, vector, color, int, bool, etc) over time, or instantly. Good examples would be the alpha of a CanvasGroup, or the volume of an AudioSource.

If your use case matches, then using that class as a base will save you a lot of time. You can look at the MMFeedbackCanvasGroup for a reference of how it’s done.

using MoreMountains.Tools;
using UnityEngine;

namespace MoreMountains.Feedbacks
{
    /// <summary>
    /// This feedback lets you control the opacity of a canvas group over time
    /// </summary>
    [AddComponentMenu("")]
    // displays a help text in the inspector
    [FeedbackHelp("This feedback lets you control the opacity of a canvas group over time.")]
    // path to add the feedback in the Add Feedback dropdown
    [FeedbackPath("UI/CanvasGroup")]
    // IMPORTANT : we make sure we extend MMFeedbackBase
    public class MMFeedbackCanvasGroup : MMFeedbackBase
    {
        /// sets the inspector color for this feedback
#if UNITY_EDITOR
        public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.UIColor; } }
#endif

        // below we declare a number of properties that are specific to our use case
        // for each value you'll want to have a MMTweenType curve to move over, a target, remap zero and one values, and a value to apply on instant

        [Header("Target")]
        /// the receiver to write the level to
        public CanvasGroup TargetCanvasGroup;
        [Header("Level")]
        /// the curve to tween the intensity on
        [MMFEnumCondition("Mode", (int)MMFeedbackBase.Modes.OverTime, (int)MMFeedbackBase.Modes.ShakerEvent)]
        public MMTweenType AlphaCurve = new MMTweenType(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
        [MMFEnumCondition("Mode", (int)MMFeedbackBase.Modes.OverTime, (int)MMFeedbackBase.Modes.ShakerEvent)]
        public float RemapZero = 0f;
        /// the value to remap the intensity curve's 1 to
        [MMFEnumCondition("Mode", (int)MMFeedbackBase.Modes.OverTime, (int)MMFeedbackBase.Modes.ShakerEvent)]
        public float RemapOne = 1f;
        /// the value to move the intensity to in instant mode
        [MMFEnumCondition("Mode", (int)MMFeedbackBase.Modes.Instant)]
        public float InstantAlpha;

        // this method is where the magic happens.
        // we create a base target and a receiver. We bind our receiver's object and specify what property we want to impact on it
        // then we setup our MMFeedbackBaseTarget, and finally we add it to our list of targets. That's all!

        protected override void FillTargets()
        {
            if (TargetCanvasGroup == null)
            {
                return;
            }

            MMFeedbackBaseTarget target = new MMFeedbackBaseTarget();
            MMPropertyReceiver receiver = new MMPropertyReceiver();
            receiver.TargetObject = TargetCanvasGroup.gameObject;
            receiver.TargetComponent = TargetCanvasGroup;
            receiver.TargetPropertyName = "alpha";
            receiver.RelativeValue = RelativeValues;
            target.Target = receiver;
            target.LevelCurve = AlphaCurve;
            target.RemapLevelZero = RemapZero;
            target.RemapLevelOne = RemapOne;
            target.InstantLevel = InstantAlpha;

            _targets.Add(target);
        }

    }
}

Extensions Repository

If you create a new feedback and think others might benefit from it, or if you’re looking for more feedbacks or Feel tools, you can check the Feel Extensions Repository on Github. Contributions are of course always welcome!