View Full Version : Need to run script when attribute changed.

10 October 2010, 07:03 PM
Hey. I'm trying to set up the FK IK arm matching script, and I'm trying to set up a script job to run when an enum attribute is changed from "FK" to "IK"

I figured I set up a global proc for when the FK matches to IK, then when they IK matches to FK, then make one that's an if statement, so if the enum is switched to FK, is run the FK script, or if it's switched to IK, it runs the IK script. But for some reason I'm getting stopped at the if statement part and I'm sure it's something stupid I missed, but right now I can't figure out what it is, and the if statement doesn't work.

So if anybody has any ideas here, help would be appreciated right now.
Here's what I've got so far, with the if statement as just a test. I've been looking around for more info on this, but it's not the easiest term to search for.
Global Proc fk2ik()

//Start of fk to ik matching code
// Get the XYZ Rotation values of the ik shoulder joint
float $L_ShoulderRX = `getAttr l_shoulder_a_ikRIG.rx`;
float $L_ShoulderRY = `getAttr l_shoulder_a_ikRIG.ry`;
float $L_ShoulderRZ = `getAttr l_shoulder_a_ikRIG.rz`;
// Get the Y Rotation value of the ik Elbow joint
float $L_ElbowRX = `getAttr l_elbow_a_ikRIG.rx`;
float $L_ElbowRY = `getAttr l_elbow_a_ikRIG.ry`;
float $L_ElbowRZ = `getAttr l_elbow_a_ikRIG.rz`;
// Get the XYZ Rotation values of the ik wrist joint
float $L_WristRX = `getAttr l_hand_a_ikRIG.rx`;
float $L_WristRY = `getAttr l_hand_a_ikRIG.ry`;
float $L_WristRZ = `getAttr l_hand_a_ikRIG.rz`;
//Apply those values to the fk bones and that will “snap” the fk arm to the ik arm
// Match the XYZ Rotation values for the fk shoulder joint
setAttr lf_shoulder_fkCTRL.rx $L_ShoulderRX;
setAttr lf_shoulder_fkCTRL.ry $L_ShoulderRY;
setAttr lf_shoulder_fkCTRL.rz $L_ShoulderRZ;
// Match the Y Rotation value for the fk elbow joint
setAttr lf_elbow_fkCTRL.rx $L_ElbowRX;
setAttr lf_elbow_fkCTRL.ry $L_ElbowRY;
setAttr lf_elbow_fkCTRL.rz $L_ElbowRZ;
// Match the XYZ Rotation values for the fk wrist joint
setAttr lf_Hand_CTRL.rx 0;
setAttr lf_Hand_CTRL.ry 0;
setAttr lf_Hand_CTRL.rz 0;
// End of fk to ik matching code

Global Proc ik2fk()
//Start of ik to fk matching code
//Left Arm ik controls--> fk controls snap
// Get the XYZ Translation values from the left arm pole vector "dummy" node
// We don’t care about the rotation from the “dummy” node
float $LelbowDummyTX = `getAttr lf_Elbow_pv_ikLOC.tx`;
float $LelbowDummyTY = `getAttr lf_Elbow_pv_ikLOC.ty`;
float $LelbowDummyTZ = `getAttr`;
// Get the XYZ Translation values from the left Arm ik Control "dummy"
float $LwristDummyX = `getAttr lf_Hand_pv_ikLOC.tx`;
float $LwristDummyY = `getAttr lf_Hand_pv_ikLOC.ty`;
float $LwristDummyZ = `getAttr`;
//Move the Left arm Pole Vector control to the "dummy" position
setAttr lf_Hand_pv_ikLOC.tx $LelbowDummyTX;
setAttr lf_Hand_pv_ikLOC.ty $LelbowDummyTY;
setAttr $LelbowDummyTZ;
// Move and rotate the left arm ik control to the "dummy" position
setAttr lf_Hand_CTRL.tx $LwristDummyX;
setAttr lf_Hand_CTRL.ty $LwristDummyY;
setAttr $LwristDummyZ;

//End of ik to fk matching code
Global Proc test()
if (lf_Hand_CTRL.fkIkSwith = 0)
print "worked"

10 October 2010, 07:27 PM
if (lf_Hand_CTRL.fkIkSwith = 0)
the "is equal to" symbol is TWO = not one.

if (lf_Hand_CTRL.fkIkSwith == 0)also, you have use capital letters for Global Proc and I'm guessing this shouldn't work either?


10 October 2010, 07:32 PM
Yeah, I had just caught that too. I guess the case is I need the make the attribute into a float first before it would work in the if statement for some reason.

Here's what I ended up with.

global proc FKIKMatch()
float $lhandSetting = `getAttr lf_Hand_CTRL.fkIkSwitch`;

if ($lhandSetting == 0) print "Worked";


10 October 2010, 01:30 AM
Was dealing with something similar for enabling, disabling RenderMan SubD scheme.

Is setting up the expression as a "global proc" all that is needed to make it evaluate when an attr is changed? I would assume not, but would love to know the proper way to have an expression right when the value is changed rather than waiting for the time slider to move.


10 October 2010, 05:01 PM
No, I was using a script job to trigger it before. Something like:

int $leftSnapSwitchOn = ` scriptJob -attributeChange "lf_Hand_CTRL.fkIkSwitch"

"leftFKIKMatch()" ` ;

I store the script job as an integer so I can kill it if I need to with something like

scriptjob -kill $leftSnapSwitchOn

If you don't know about script jobs, once you turn them on, they're running as long as Maya is on, and you either have to close down Maya, or kill the job to stop it from running. But it'll execute the job you have it doing when ever the trigger happens after just entering the code once, even in just the script editor. I only had it as an expression so my animators wouldn't have to implement it for the specific rig.

For my needs, I'm probably switching this to a hotbox switch so it only executes just when they make the switch manual. As a script job, it's executing its self when they're scrubbing and the animation is tweening, which is the wrong time to run. It'd be only any good if I could trigger it when they manually switch the attribute, rather than when animation switches the attribute.

CGTalk Moderation
10 October 2010, 05:01 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.