This page explains how to use MMTools' attributes to improve your own inspectors.

Introduction

Feel’s own inspectors rely on a set of attributes that live in MMTools/Core/MMAttributes. You can use them in your own classes too: they’re simple attributes you add above your fields, and they let you hide or disable fields based on other values, add buttons, information boxes, foldable groups, and more, without writing a single custom editor.

All of them are in the MoreMountains.Tools namespace, so make sure you add using MoreMountains.Tools; at the top of your class.

Conditional fields

MMCondition

Shows a field only when a bool field of the same class is true. By default the field is shown but disabled when the condition isn’t met. Pass true as the second parameter to hide it entirely instead, and true as the third parameter to invert the condition.

public bool UseCustomSpeed = false;
[MMCondition("UseCustomSpeed", true)]
public float CustomSpeed = 5f;
[MMCondition("UseCustomSpeed", true, true)]
public float DefaultSpeedMultiplier = 1f; // only shown when UseCustomSpeed is false

Shows a field only when an enum field of the same class matches one of the specified values.

public enum MovementModes { Walk, Fly, Swim }
public MovementModes MovementMode = MovementModes.Walk;

[MMEnumCondition("MovementMode", (int)MovementModes.Fly, (int)MovementModes.Swim)]
public float VerticalSpeed = 2f;

Buttons

MMInspectorButton

Displays a button in the inspector that calls a method of your class when pressed. Add it on a bool field (the field itself is just a placeholder, its value doesn’t matter), and pass it the name of the method to call. The method can be public or not, and must take no parameters. The button displays the method’s name.

[MMInspectorButton("Respawn")]
public bool RespawnButton;

protected virtual void Respawn()
{
	// ...
}

This is very handy for testing things at runtime, or for editor tools. Note that the method gets called on the target object, whether you’re in play mode or not.

MMInspectorButtonBar

Similar, but displays a row of buttons. It takes an array of labels, an array of method names, an array of bools (whether each button should only be enabled in play mode), and an array of USS classes to style them.

Display

MMInformation

Displays a help box (Info, Warning, Error or None) before or after a field. These boxes can be turned on or off globally via the Tools > More Mountains > Enable / Disable Help in Inspectors menu.

[MMInformation("This sets the speed of the character, in units per second.", MMInformationAttribute.InformationType.Info, false)]
public float Speed = 5f;

MMReadOnly and MMReadOnlyWhenPlaying

MMReadOnly displays a field, but prevents it from being edited. Perfect for exposing a runtime state for debugging purposes. MMReadOnlyWhenPlaying only locks the field while in play mode.

[MMReadOnly]
public int CurrentHealth;

MMHidden

Hides a field from the inspector, while keeping it serialized (similar to Unity’s HideInInspector).

MMColor and MMBackgroundColor

MMColor(r, g, b) tints a field’s label and contents with the specified color, and MMBackgroundColor gives it a colored background (Red, Pink, Orange, Yellow, Green, Blue, Violet or White). Use them to make important fields stand out.

[MMColor(1f, 0f, 0f)]
public float DangerZone = 10f;

MMVector

Replaces the default X/Y/Z labels of a Vector2, Vector3, Vector4, Vector2Int or Vector3Int field with your own.

[MMVector("Min", "Max")]
public Vector2 DurationRange = new Vector2(1f, 2f);

Pickers

MMDropdown

Turns a string, int or float field into a dropdown, letting users pick from a predefined list of values of that same type.

[MMDropdown(30, 60, 120, 144)]
public int TargetFramerate = 60;

MMLayer

Displays an int field as a layer picker.

[MMLayer]
public int TargetLayer;

MMNavMeshAreaMask

Displays an int field as a NavMesh area mask picker.

Inspector groups and MMMonoBehaviour

Some attributes work at the class level, and require your class to extend MMMonoBehaviour instead of MonoBehaviour. MMMonoBehaviour is an empty class that extends MonoBehaviour, so switching to it doesn’t change anything to your class’ behaviour, but it gives it MMTools’ custom inspector, which unlocks the following:

MMInspectorGroup

Groups fields under foldable, colored sections, like the ones you see on Feel’s components. Its parameters are the group’s name, whether all following fields should be included until the next group attribute (otherwise only that field is), a color index, and whether the group should be closed by default.

public class MyCharacter : MMMonoBehaviour
{
	[MMInspectorGroup("Movement", true, 12)]
	public float Speed = 5f;
	public float Acceleration = 10f;

	[MMInspectorGroup("Health", true, 13)]
	public int MaxHealth = 100;
	public int CurrentHealth;
}

MMHiddenProperties

Added on a class, hides the specified fields from the inspector. Most useful when extending a class whose fields you don’t want to expose in the child class.

[MMHiddenProperties("Acceleration")]
public class MyFlyingCharacter : MyCharacter { }

MMRequiresConstantRepaint

Added on a class, forces its inspector to repaint every frame, useful if you display values that change constantly. MMRequiresConstantRepaintOnlyWhenPlaying does the same, only in play mode.

Other attributes

  • MMExecutionOrder: add it to a class to set its script execution order, without going through the project settings. For example [MMExecutionOrder(-100)].
  • MMDebugLogCommand: add it to a static method to make it callable from the MMDebugMenu’s command line.

Note that MMFeedbacks have their own versions of some of these attributes, prefixed with MMF (MMFInspectorGroup, MMFCondition, MMFEnumCondition, MMFInspectorButton…). Use these when writing custom feedbacks, and the MM ones for your regular components.