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.Tools;

namespace MoreMountains.Feedbacks
{
    [AddComponentMenu("")]
    [FeedbackHelp("You can add a description for your feedback here.")]
    [FeedbackPath("ChosenPath/MyFeedbackNameGoesHere")]
    public class MMF_DebugLog : MMF_Feedback
    {
        /// a static bool used to disable all feedbacks of this type at once
        public static bool FeedbackTypeAuthorized = true;
        /// use this override to specify the duration of your feedback (don't hesitate to look at other feedbacks for reference)
        public override float FeedbackDuration { get { return 0f; } }
        /// pick a color here for your feedback's inspector
    		#if UNITY_EDITOR
    			public override Color FeedbackColor { get { return MMFeedbacksInspectorColors.DebugColor; } }
    		#endif

    		protected override void CustomInitialization(MMF_Player owner)
    		{
    			base.CustomInitialization(owner);
    			// your init code goes here
    		}

        protected override void CustomPlayFeedback(Vector3 position, float feedbacksIntensity = 1.0f)
        {
            if (!Active || !FeedbackTypeAuthorized)
            {
                return;
            }            
            // your play code goes here
        }

        protected override void CustomStopFeedback(Vector3 position, float feedbacksIntensity = 1)
        {
	        if (!FeedbackTypeAuthorized)
	        {
		        return;
	        }            
	        // your stop code goes here
        }
    }
}

Creating a new feedback (for the legacy MMFeedbacks system)

Creating a new feedback for the legacy system is also very simple. 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!