gonzalimator
03-18-2009, 01:25 AM
Hi,
I'm new to mel and rigging. I'm having problems with this script/scriptJob that is meant for space switching. It's for a toy windmill prop and I'm trying to set up the blades of the windmill with two parents, the toy itself and the world.
The setup I've made is like this: the windmill has two controls, a "main_ctrl" and a "blades_ctrl". The blades_ctrl is a child of a group called "blades_spaceSwitch_grp". The blades_spaceSwitch_grp is a child of another group named "blades_ctrl_cnst" which has one parent constraint constraining it to the main_ctrl. For space switch matching I'm using a null parented under the main_ctrl (pivot and position matches the blades_ctrl exactly).
Heirarchy:
blades_ctrl_cnst (constrained to main_ctrl)
> blades_spaceSwitch_grp (has enum attr named "parent", values "free" and "attached")
-> blades_ctrl (has the same "parent" enum attr but is non-keyable)
Connections:
The blades_ctrl.parent triggers the script like it was a button. The blades_spaceSwitch_grp.parent is directly connected to the weight of the blades_ctrl_cnst parent constraint.
What I'm trying for besides the seamless space switch is to set a key on the spaceSwitch_grp on the previous frame with the previous parent/position condition and a key on the current frame with the new parent/position.
Here's the code:
// ADD NAMESPACE HERE
global string $ns = "";
proc matchBlades()
{
// declare variables for script
global string $ns;
// match object info
$bt = `xform -query -worldSpace -rotatePivot ($ns+"blades_ctrl_match")`;
$br = `xform -query -worldSpace -rotation ($ns+"blades_ctrl_match")`;
// spaceSwitch current info
$curPos = `getAttr ($ns+"blades_spaceSwitch_grp.translate")`;
$curRot = `getAttr ($ns+"blades_spaceSwitch_grp.rotate")`;
// current and new parent info
$curState = `getAttr ($ns+"blades_spaceSwitch_grp.parent")`;
$newState = `getAttr ($ns+"blades_ctrl.parent")`;
// current and previous frame info
$curFrm = `currentTime -query`;
$prevFrm = ($curFrm - 1);
// match blades to the match object when the parent switch is changed to "free"
if ($newState == 0)
{
setKeyframe -time $prevFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
move -rpr $bt[0] $bt[1] $bt[2] ($ns+"blades_spaceSwitch_grp");
rotate -a -worldSpace $br[0] $br[1] $br[2] ($ns+"blades_spaceSwitch_grp");
setAttr ($ns+"blades_spaceSwitch_grp.parent") 0;
setKeyframe -time $curFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
}
else //zero out the blades bringing them back to the windmill
{
setKeyframe -time $prevFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
setAttr ($ns+"blades_spaceSwitch_grp.translate") 0 0 0;
setAttr ($ns+"blades_spaceSwitch_grp.rotate") 0 0 0;
setAttr ($ns+"blades_spaceSwitch_grp.parent") 1;
setKeyframe -time $curFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
}
//key the blades control
setKeyframe -time $curFrm ($ns+"blades_ctrl");
}
// execute script when the "Parent" attribute changes
$bMatchJob = `scriptJob -ac ($ns+"blades_ctrl.parent") matchBlades`;
//
I've seen awkward space switching scriptJobs that are triggered by an attribute that is keyable. I've found that you can't scrub the time line and expect the scriptJobs to trigger, or you get into weird loops when you undo (I undo keying the parent attr and the scriptJob triggers again unintentionally) I've gotten the individual pieces of my script to work, but I can't get the setKeyframe command to work consistently. It always keys the same values on both the previous and current frames. I printed the variables and they all look okay. What am I not getting?
(I know there are easier ways to animate the windmill blades' connection but I'm trying to learn this technique so I can use it in the future.)
Help!! (please)
Marcos
I'm new to mel and rigging. I'm having problems with this script/scriptJob that is meant for space switching. It's for a toy windmill prop and I'm trying to set up the blades of the windmill with two parents, the toy itself and the world.
The setup I've made is like this: the windmill has two controls, a "main_ctrl" and a "blades_ctrl". The blades_ctrl is a child of a group called "blades_spaceSwitch_grp". The blades_spaceSwitch_grp is a child of another group named "blades_ctrl_cnst" which has one parent constraint constraining it to the main_ctrl. For space switch matching I'm using a null parented under the main_ctrl (pivot and position matches the blades_ctrl exactly).
Heirarchy:
blades_ctrl_cnst (constrained to main_ctrl)
> blades_spaceSwitch_grp (has enum attr named "parent", values "free" and "attached")
-> blades_ctrl (has the same "parent" enum attr but is non-keyable)
Connections:
The blades_ctrl.parent triggers the script like it was a button. The blades_spaceSwitch_grp.parent is directly connected to the weight of the blades_ctrl_cnst parent constraint.
What I'm trying for besides the seamless space switch is to set a key on the spaceSwitch_grp on the previous frame with the previous parent/position condition and a key on the current frame with the new parent/position.
Here's the code:
// ADD NAMESPACE HERE
global string $ns = "";
proc matchBlades()
{
// declare variables for script
global string $ns;
// match object info
$bt = `xform -query -worldSpace -rotatePivot ($ns+"blades_ctrl_match")`;
$br = `xform -query -worldSpace -rotation ($ns+"blades_ctrl_match")`;
// spaceSwitch current info
$curPos = `getAttr ($ns+"blades_spaceSwitch_grp.translate")`;
$curRot = `getAttr ($ns+"blades_spaceSwitch_grp.rotate")`;
// current and new parent info
$curState = `getAttr ($ns+"blades_spaceSwitch_grp.parent")`;
$newState = `getAttr ($ns+"blades_ctrl.parent")`;
// current and previous frame info
$curFrm = `currentTime -query`;
$prevFrm = ($curFrm - 1);
// match blades to the match object when the parent switch is changed to "free"
if ($newState == 0)
{
setKeyframe -time $prevFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
move -rpr $bt[0] $bt[1] $bt[2] ($ns+"blades_spaceSwitch_grp");
rotate -a -worldSpace $br[0] $br[1] $br[2] ($ns+"blades_spaceSwitch_grp");
setAttr ($ns+"blades_spaceSwitch_grp.parent") 0;
setKeyframe -time $curFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
}
else //zero out the blades bringing them back to the windmill
{
setKeyframe -time $prevFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
setAttr ($ns+"blades_spaceSwitch_grp.translate") 0 0 0;
setAttr ($ns+"blades_spaceSwitch_grp.rotate") 0 0 0;
setAttr ($ns+"blades_spaceSwitch_grp.parent") 1;
setKeyframe -time $curFrm -outTangentType step ($ns+"blades_spaceSwitch_grp");
}
//key the blades control
setKeyframe -time $curFrm ($ns+"blades_ctrl");
}
// execute script when the "Parent" attribute changes
$bMatchJob = `scriptJob -ac ($ns+"blades_ctrl.parent") matchBlades`;
//
I've seen awkward space switching scriptJobs that are triggered by an attribute that is keyable. I've found that you can't scrub the time line and expect the scriptJobs to trigger, or you get into weird loops when you undo (I undo keying the parent attr and the scriptJob triggers again unintentionally) I've gotten the individual pieces of my script to work, but I can't get the setKeyframe command to work consistently. It always keys the same values on both the previous and current frames. I printed the variables and they all look okay. What am I not getting?
(I know there are easier ways to animate the windmill blades' connection but I'm trying to learn this technique so I can use it in the future.)
Help!! (please)
Marcos
