It is possible to create scripts in MEL which will run whenever a particular system event occurs. This is done using the scriptJob command. Maya defines a number of system events that you can attach scripts to. These events are triggered by the normal use of Maya. There are events that tell you when the selection has changed, when a new file has been opened, and when a new tool is picked.
You can get a complete listing of all the events using the scriptJob command with the -listEvents flag: scriptJob -listEvents; The names of these events is generally self-explanatory; detailed descriptions can be found in the scriptJob documentation.
There is another kind of system event called a condition. A condition is like an event, except that is also has a value of either true or false. For example, there are conditions that tell you when something is selected, or when an animation is playing back. You can get a complete list of all conditions using the scriptJob command with the -listConditions flag:
scriptJob -listConditions;
A condition triggers its attached scripts whenever its state changes from true to false, or from false to true. You can test its state at any time using the isTrue command.
Finally, there is an event generated when the value of an attribute of an object changes. When you attach a script to an event or a condition, it doesn’t run right away. When the event or condition is triggered, the script is added to a queue and is run the next time the system is idle. No matter how many times the event or condition is triggered during a busy time, the script will only run once the next time the system is idle.
Important Note: scriptJobs only work when you are running Maya with its graphic user interface.
They do not work in batch mode or prompt mode. They are meant to be used to customize your user interface. Don’t try to use them to make things happen during the running of an animation, because they will not execute during playback or batch rendering. Use expressions instead.
Let’s say for example that you want to write a script which will select a particular object whenever nothing else is selected. Here is a script to select the object:
select -r myObject;
You want this to run whenever nothing is selected. There is a condition called “SomethingSelected” which is true only when something is selected. When this condition becomes false, you want to run your script. Here is the command to do this:
scriptJob -conditionFalse "SomethingSelected" "select -r myObject";
For another example, let’s say instead that you want your object to always be selected. You can have a scriptJob that runs every time the selection changes and insures that your object is there:
scriptJob -event "SelectionChanged" "select -add myObject";
In this example, you want to warn yourself if an object in your scene goes up too far. You can have a script that will check the translateY value of the object whenever it changes:
global proc checkY(){ float $y = `getAttr myObject.ty`; if ( $y > 10.0 ){ window; columnLayout; text -l "Object is too far up!"; showWindow; } } scriptJob -attributeChange "myObject.ty" "checkY";
When you use the scriptJob command to attach a script to an event or condition, the command returns a unique “job number”. You can use this number to delete (kill) the jobs you have created. Let’s say the example above returned the number 17. To stop this script from running any more, you can use the scriptJob command with the -kill flag, like this:
scriptJob -kill 17;
To get a complete listing of all the scriptJobs running in the system, use the -listJobs flag:
scriptJob -listJobs;
This returns a list of job numbers, followed by all the flags and arguments used by the scriptJob command to create the job in the first place.
There are a number of ways you can cause jobs to kill (delete) themselves automatically. If you create the job with the -runOnce flag set to true, the job will only run one time, and then delete itself.
You can use the -parent flag to attach a job to a particular element of the UI, so that when the UI element is deleted, the job is deleted with it. This next example creates a window. A scriptJob is used to update the text in the window, which says whether or not something is selected. When the window is deleted, the job is killed automatically:
global proc updateSelWind(){ if ( `isTrue SomethingSelected` ){ text -edit -label "Something is selected." selText; } else { text -edit -label "Nothing is selected." selText; } } string $windowName = `window`; columnLayout; text selText; updateSelWind; showWindow $windowName; scriptJob -parent $windowName // attach the job to the window -conditionChange "SomethingSelected" "updateSelWind";
Normally, running jobs are not displayed in the Script Editor window. You can get them to display, however, by turning on the “Echo All Commands” options in the Edit menu of the Script Editor.