Command Creation
Declaring a Command
MonKey recognizes commands to add to the console with attributes.
To make a method a command recognizable by MonKey, the method must be static. Simply add a [Command] Attribute to it, and you are done!
An example of usage of the Command Attribute (Source Text Here)
Important: The c# file holding the command must be in an editor folder in order for it to compile: MonKey is not designed to work in runtime, so all the scripts using it must be placed in an editor folder.
The command attribute comes with a whole set of options:
Name And Help
Name: The name of the command as seen in the MonKey console.
Quick Name: The Quick Name will appear before the name of the command, and should be thought as a quicker way to find the command. We recommend not using more than 3 characters for the quick names.
Help: The help that will appear under the command name. The Help can be as long as you wish, however if the text is longer than one line the formatting may not be perfect.
Command Visibility
AlwaysShow: if true, the command will appear in the list of commands shown when you open the console.
Order: The Smaller the number, the higher the order of the command. If the command is marked "AlwaysShow", it will influence the position of the command on the initial list.
The order also influences the order in which the command will show when two commands could equally fit the search terms entered.
IgnoreHotKeyConflict: If true, the command will not show a warning if two hotkeys are identical. This can be useful when the hotkeys share a different context.
Command Validation
DefaultValidation: You can specify a validation for the command among the default ones available. The command will not be available if teh validation condition is not met.
Here is the list of default validations available:
- AT_LEAST_ONE_GAME_OBJECT,
- AT_LEAST_TWO_GAME_OBJECTS,
- AT_LEAST_ONE_OBJECT,
- AT_LEAST_TWO_OBJECTS,
- AT_LEAST_ONE_TRANSFORM,
- AT_LEAST_TWO_TRANSFORMS,
- IN_PLAY_MODE,
- IN_EDIT_MODE,
- IN_PLAY_MODE_AT_LEAST_ONE_GAME_OBJECT,
- IN_PLAY_MODE_AT_LEAST_TWO_GAME_OBJECTS,
- IN_PLAY_MODE_AT_LEAST_ONE_OBJECT,
- IN_PLAY_MODE_AT_LEAST_TWO_OBJECTS,
- IN_PLAY_MODE_AT_LEAST_ONE_TRANSFORM,
- IN_PLAY_MODE_AT_LEAST_TWO_TRANSFORMS,
- IN_EDIT_MODE_AT_LEAST_ONE_GAME_OBJECT,
- IN_EDIT_MODE_AT_LEAST_TWO_GAME_OBJECTS,
- IN_EDIT_MODE_AT_LEAST_ONE_OBJECT,
- IN_EDIT_MODE_AT_LEAST_TWO_OBJECTS,
- IN_EDIT_MODE_AT_LEAST_ONE_TRANSFORM,
- IN_EDIT_MODE_AT_LEAST_TWO_TRANSFORMS,
- AT_LEAST_ONE_ASSET,
- AT_LEAST_ONE_SCENE_OBJECT,
- AT_LEAST_ONE_FOLDER
ValidationMethodName: If you need to define your own validation method (if for instance the default validations are not enough), you can enter here the name of the validation method. The validation method needs to be present in the same class, and be static. It needs to return a bool that will be evaluated when the command is selected in the console.
Menu Item Link
If you want the command to have a hotkey, you must add a MenuItem attribute on the same command like you would normally in Unity.
However in some cases you want to define the menu item in a different method than the one with the command attribute, these parameters are made for that:
MenuItemLink: The name of the menu item method that will be linked to the command.
MenuItemLinkTypeOwner: The class that holds the menu item method, to specify only if the menu item method is not in the same class as the command.
This simply calls the Duplicate command from MonKey (Source Text)
In order for the menu item to not be listed by MonKey and to have it properly linked to a command, you must add a MenuItemCommandLink attribute to the MenuItem method.
If you do not add this attribute, the "Duplicate" command will appear twice: it will be once detected as a menu item by MonKey, and once as the command: this attribute is here to tell MonKey that the method is just here to associate the hotkey of the menu item to the command, and that it shouldn't be listed as a menu item in the console.
Declaring a Command Validation
If you want to use a command validation that is not part of the default available ones, you can create a validation method by adding a CommandValidation attribute to a static method returning a bool.
This Validation will let the command execute only if more than one transform was selected (Source Text)
The validation method must be present in the same class as the command. You can specify in the attribute the warning message that will show up if the validation criteria isn't met when trying to use the command.
Parametric Commands
Contrary to Unity's MenuItem, MonKey allows you to create commands with parameters.
Here are the types of parameters that are supported by default:
- String
- Int
- Float
- Double
- Byte
- Bool
- Char
- Long
- Short
- Enum
- Vector2
- Vector3
- Vector4
- Quaternion
- Color
- Object (Unity's, and all class deriving from Object)
- Component (and all classes deriving from Component)
- GameObject
- LayerMask
- Scene
- Type
- Arrays
Note: In order to not complicate the interface for entering parameters in the console, Lists, Dictionaries, and other Enumerable types are not supported. Think about the parameters of your commands as the way your users will use it: while you can write your own interpreter to support any type you wish, we recommend to keep the parameters types simple.
Using any data structures complicates the way the command user can use the command, and arrays prove to already introduce complexity.
Declaring a Command Parameter
If your commands has parameters with supported types, it will automatically work as such if you add a Command attribute. However, it is possible to add a lot of customization to the way parameters are handled:
On Method or On Parameter
You can use the parameter attribute on the method, or on the parameter, depending on your preferences. If you want to use it on the method, you will need to specify the Order parameter of the attribute. This represents the order of the parameter on the method, starting with 0. If you put the attribute on the parameter directly, you can ignore the order.
On the method can look cleaner, but may be a bit harder to understand
On the parameter may be harder to read, but easier to understand
Default Value
You can define the default value of your parameters the way you would normally do in C#, and it will show accordingly in the interface. You may as well customize the default value:
DefaultValueMethod: You can define your own default value method. This is useful when the default value cannot be precompiled, for instance when you want an object to be by default the first object selected.
For instance, linking this method as the default value of a GameObject parameter will make it the first object selected by default (Source Text Here)
DefaultValueNameOverride: Specify here the way the default value will be formatted on the interface (for instance for the example above, you could enter "First Object Selected"
PreventDefaultValueUsage: If true, then the command won't execute when the user presses CTRL+ENTER to execute it with default values: as long as the parameter was not manually entered, this will be unavailable.
User Formatting
Few Option let you modify the way the parameter will be shown:
Help: You can specify here the help that will be shown on the side when editing the parameter.
OverrideName: If you want the name shown in the interface to be different from the name of the variable, you can specify here the name you would like to show. Note that the parameter names are already formatted by MonKey (parameterName will show as Parameter Name)
OverrideTypeName: If you want the type of the parameter to be shown with a different name, you can specify it here. This can be useful when you want to hide the actual type of parameter when this would be confusing to your user.
DefaultValueNameOverride: Same thing for the default value of the parameter as shown to the user: you can change the name shown here. This can be useful together with DefaultValueMethod to make sure the user knows what will be the behavior of the command when no value is entered.
Auto Complete
The auto complete functionality shows to your user suggested values under the input. For all types supported by MonKey, a default autocomplete is available. However for custom scenarios you can define it yourself.
ForceAutoCompleteUsage: If true, then the user will not be allowed to enter any value: the value will automatically be chosen from the suggested values if none was selected. This is useful when you want to make sure the value given will be correct. For instance, the "Find Asset" command uses this to make sure that the asset name found is correct.
AutoCompleteMethodName: If you want to use a custom auto-complete list of available values, you can specify here the method that will return the autocomplete structure.
An example of this is if you want to use a string that represent an asset path. An autocomplete method is available for that directly in MonKey, but you will need to specify it (as not all string are meant to represent an asset path).
The method you specify here must return a GenericCommandParameterAutoComplete. Most of the time it is easier to make the method return one of the utilities available in MonKey by default:
- By using the AutoCompleteManager, a static class that contains default auto-completes for all supported types, and auto-completes for asset names, layer, and tags.
- By using one the implementations of the class present in MonkeyAutoComplete.cs: AssetNameAutoComplete for asset path displayed in the way the "Find Asset" Command does, ColorAutoComplete for colors displayed as in the measurement commands, TypeAutoComplete for type displayed as in the "Replace Component" command.
- By using a CommandParameterAutoComplete<T> or a CommandParameterObjectAutoComplete<T> (for Unity Objects, with a nicer dropdown look). These are readonly Autocompletes to which you can add values within your autocomplete method to have them available in the autocomplete. Please note that these two classes only allow you to create a non modifiable list of suggested values: if you want an autocomplete that search through the assets, you will need to use the first option or write your own autocomplete class (see below).
An Example of AutoComplete that returns all the rigidbodies present in the selection (Source Text Here)
GenericCommandParameterAutoComplete
The base class understood by MonKey as a provider of value for a text entered in the interface. Extend this class if you want a specific behavior for your autocomplete.
ParameterType: this needs to be specified in the constructor, it simply is the type of object you are creating an autocomplete for.
InitializeAutoComplete: This method is called when the parametric panel is opened in the console, and the parameter concerned is visible. If you need to initialize the autocomplete so that it capture the current state of the selection for instance, you must do it here.
GenerateAndSortAutoComplete: This method is called every time the user enters a text in the search bar. You should sort suggestions by relevance, and find the values to display. A lot of helper methods are present in StringExt (see Code Reference for more info) to let you use the same sorting algorithm as MonKey.
Count: Should return the amount of suggested values currently visible
GetValue: Given the selected ID in the interface (in the drop down list), should return the corresponding object
GetStringValue: The string representation of the object that will be displayed on the dropdown list, and that will appear in the search field when the user is editing the value again later.
SearchInstruction: You can modify the text that appears in the background of the search field here to fit better the type of object. If you do not specify anything here, the default message will be used.
DrawAutoComplete: Here you can change the way the values are displayed in the dropdown zone. In order to fit MonKey's style, you can find Textures, Colors and Styles under MonKeyStyle.cs (see Code Reference for more info).
This way, you can show your values the exact way you want. You can for instance insert an icon representing the value next to the name, like for the "Find Asset" Command. This however requires you to be familiar with the EditorGUI of Unity.
Here is the AutoComplete as display in the "Find Asset" Command. In order to get a similar look, you can as well use the AssetNameAutoComplete present in the AutoCompleteManager (Source Text Here)
Parameter Type Interpreter
If you want to add support to a type of parameter that is not supported by default by MonKey, you will need to create an new CommandParameterInterpreter and register it with an InitializeOnLoad method.
Please note that you do not need to create an interpreter if you just use parameters in the type mentioned earlier.
Constructor: You must specify here the type that the interpreter is outputting.
Add Interpreter: You must add an [InitializeOnLoadMethod] attribute on a static method in which you call "AddInterpreter" (a static method). This will register your interpreter inside MonKey, allowing your type to be interpreted in the console.
TryParse: Here you should put the logic that transform a text entered by your users into the corresponding object. The method should return true if the parsing was done without errors. SubType is useful when you want to create an interpreter that can concern few subtypes, for instance a UnityEngine interpreter may need to know the type of object in order to return the proper one with Resources.FindObjectsOfTypeAll(subType)
Creating a Scene Command
Scene Commands are interactive commands that will appear in the scene view.
To Create a Scene Command, you need two things:
- A SceneCommand class that will handle the scene logic.
- A normal Command method that will create your Scene Command and assign it to MonKey
Adding a Scene Command
To add a scene command active on the scene within MonKey's interface, you simply need to call MonkeyEditorUtils.AddSceneCommand and specify as a parameter a new instance of your Scene Command.
For that Scene Command to be available through the MonKey console, simply call this within a static editor method with a command attribute, like for a normal MonKey command.
Declaring a Scene Command
When declaring a new Scene Command class, you must inherit it from any of those classes:
- SceneCommand
- ConfirmedCommand
- TimedSceneCommand
- InteractiveCommand
- TimedMultiSceneCommand
SceneCommand
The basic class to inherit from, it contains no specific logic, and you must define the following methods:
Update: This method is called every Unity Editor Update. This is called whether the scene view is focused or not, you can put there the real time logic of your command.
OnSceneGUI: This method is called when the MonKey Scene Command GUI is drawn. Some logic is not allowed by Unity on Update, like anything involving Gizmos or Handles. If you want to display any GUI, you can do it here.
Stop: Any logic that should happen once the command is stopped by the user or by MonKey should happen here, for instance registering Undo operations.
ConfirmedCommand
Inherit this class if you want your scene command to ask for a key press confirmation to be stopped.
You can change the key used for confirmation with ActionConfirmationMode, or change the confirmation message by overriding ConfirmationMessage.
TimedSceneCommand
Inherit this class if you want your scene command to automatically stop after some time (or execute indefinitely by putting the duration to 0)
InteractiveCommand
Inherit this class if you want your command to have a confirmation key on which an action is performed, and a stop key, like for the command New Instance Under Mouse. For consistency reasons, you should not change the confirmation key, and leave the default SPACE key so that the usage remains similar to other commands.
TimedMultiSceneCommand
Inherit this class if you want your scene command to combine few existing ones into one. This class functions the same way as TimedSceneAction.