Can Enums Trigger Scripts?

I was thinking about a rigging setup that I was working on, and thought it could be neat, if triggering a change in an enum attribute on a control, would trigger a script to be run. Is there any way to set this up without making use of a script job?

The specific example I'm looking into, would be to change the enum on an elbow controller, to cause a wrist controller to snap to another control's world space position. Any ideas?

QUOTE(molemansd7 @ 09/27/08, 10:21 PM) [snapback]292430[/snapback]
I was thinking about a rigging setup that I was working on, and thought it could be neat, if triggering a change in an enum attribute on a control, would trigger a script to be run. Is there any way to set this up without making use of a script job?

Yes expressions.

Would you go about that with an If-->Then statement, or is there another way to set it up? I would only want this to execute on the change itself, not constantly evaluate.

Well thats kindof the idea under which maya dg works. IT does not evaluate unless theres change. Now expressions have a allways update option for those peopel who do not really know how to do expressions in first place (trust me there's really NO reason for this flag to exist other than letting people do worse performance because they are lazy, one can always listen to time). If you uncheck it then you dont really need any if. As maya will only trigger when its changed. As a matter of fact this option should always be unchecked for most epressions.

aigh....touche. I forgot about how maya only evaluates things that have been updated or changed. I'll poke around with this a bit and see what happens. Thanks!

I've been trying to figure out how to actually make this work the way I intend, but can't find a way to have an expression execute when the enum changes. Say, I would want to create a sphere when the enum changes to green, and a cube when it changes to blue (default settings). How could this be done?

CODE
file -f -new;
sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 1;objectMoveCommand;
move -r 5.686626 0 0;
addAttr -ln "enum" -at "enum" -en "Green:Blue:"  |nurbsSphere1;
addAttr -ln "enumpass" -at long    |nurbsSphere1;

setAttr -e -keyable true |nurbsSphere1.enum;
setAttr -e -keyable true |nurbsSphere1.enumpass;
expression -s ("int $a=nurbsSphere1.enum;\r\n"+
               "nurbsSphere1.enumpass=$a;"+
               "//something must call the trigger downsream\r\n"+
               "switch ($a) { \r\n"+
              "  case 0: \r\n"+
              "      sphere;\r\n"+
              "      break;\r\n"+
              "    case 1: \r\n"+
              "      polyCube;\r\n"+
              "} select nurbsSphere1;\r")  -o nurbsSphere1 -ae 0 -uc all;

Remember mayas a lazy evaluator something needs to change that affects the dg or the gui for maya to evaluate things.

I see...so connecting the enumpass causes the dg to update, allowing maya to execute the script. I thought that simply changing the enum would be enough to do that. I assume it would have been if something were being controlled by it. Thanks!

Just one more quick question... in the script you make the enumpass attribute type "long." I've never heard of that before...what is a "long" attribute?

edit
I see it refers to an integer attribute...now it's making sense

Type of attribute
Flag and argument to use
32 bit integer -at long
16 bit integer -at short
8 bit integer -at byte

QUOTE(molemansd7 @ 09/29/08, 11:05 PM) [snapback]292524[/snapback]
I see...so connecting the enumpass causes the dg to update, allowing maya to execute the script.

Yes bacuas may works this way:

attribute(clean)

attribute changed (clean, but is unclean for a while)

attribute down line (markked unclean)
.... ad infinitum

gui checks to see what it is concerned of if they are dirty if so they get cleaned wich cause s the reverse cycle back again.

attribute down line (requests its values cleaned)
...

attribute(clean) gets requested

node for attribute down line now refreshes
....

untill important item is clean

So, I was playing with this a bit in Maya, to make sure I could actually make it happen on my own, and I noticed that if you scrub the timeline, Maya is constantly evaluating the node, so its always making spheres and cubes. So, for my purposes of wanting to put this in a rig setup, that wouldn't do. I think it would slow it down way too much. BUT I found out you can stick an 'if' statement in the cases. So, if something is setup the way it should be, the rest of the script can be ignored, otherwise, execute it. It looks like this:

CODE
switch ($a)
{
case 0:
   if ($a != o)
   sphere;
   break;
}

So, I know that's redundant, but it shows that you can stop what would be executed...thus successfully implementing an if statement into the case. This is fun. I've never had to use a switch statement before, so this is all new ground. Me likey.

Well see now if it does that every frame then you have the

-ae 1 wich is allways update wich i specifically told you NOT to use. Your just perpetually wasting time on the if clause. In the script editor make sure the Evaluation drop down is set to On Demand. The default is the stupid setting. So if you didnt change it it will NOT work. Also please note you can not compound may options to the test as maya runs the entire script on every single testing condition change.

If you neglect thisthen yes maya will run each frame. I kind of told you not to do this. But yes if you want to do this then use a secondary attribute that refects the original

PS: maya is designed so that the dag network is static during runtime!

Ah, right. When I was recreating what you did, I was too focused on the actual formatting and syntax for the switch statement itself, and neglected the last couple flags you setup at the end of the expression command. I didn't specify anything in my code, so it used the default. BUT, now I'm more aware of it. It worked fine when I built it in the actual expression editor, since I do always set that. Thanks for the reminder.

Yeah theres much to get absolutely right in one go

Hi there I know this is many years late but I thought I’d try my luck and get a response.

Everything you guys talked about works just fine, except if the attribute is part of a character set. Being part of a character set seems to force the attribute to evaluate regardless of whether -ae is set properly. haha curses!

This is a pretty niche Maya problem so any help would be greatly appreciated.

EDIT/SOLVED. Making sure the enums that trigger the scriptNodes are NOT part of the character set (or even on another control with attributes that are in the character set) solves the evaluation problem for me. Maya apparently treats character sets a little bit differently when you scrub the timeline.

Also to anyone attempting this I would recommend putting everything in a ScriptNode instead of a ScriptJob so that it gets saved with the file. Go into the Expression Editor and go to Select>By Script Node Name. When you create your scripts as Script Nodes they will be saved with the file and your animator will never have to load a ScriptJob. For an example, my script ended up looking something like this:

 global proc lARMFKproc()

 {
int $v_lArmFK = `getAttr global_CTRL.LArmFKIK`;
if ( $v_lArmFK == 0){

$v_l_arm_fk_to_ik = `xform -query -a -ws -rotation l_arm_ik`;
$v_l_forearm_fk_to_ik = `xform -query -a -ws -rotation l_forearm_ik`;
$v_l_hand_fk_to_ik = `xform -query -a -ws -rotation l_hand_ik`;
xform -a -ws -rotation $v_l_arm_fk_to_ik[0] $v_l_arm_fk_to_ik[1] $v_l_arm_fk_to_ik[2] l_arm_fk_CTRL;
xform -a -ws -rotation $v_l_forearm_fk_to_ik[0] $v_l_forearm_fk_to_ik[1] $v_l_forearm_fk_to_ik[2] l_forearm_fk_CTRL;
xform -a -ws -rotation $v_l_hand_fk_to_ik[0] $v_l_hand_fk_to_ik[1] $v_l_hand_fk_to_ik[2] l_hand_fk_CTRL;
}
}
scriptJob -attributeChange "global_CTRL.RArmFKIK" "lARMFKproc";

Hope this helps anyone in this decade, haha

1 Like