View Full Version : Is there a way to get an expression to execute on an action?

02 February 2011, 10:28 PM
So I've been flooding this thread with questions along this line. I've got a tail I'm making that has two level of controls so there aren't so many to work with unless needed. It's 9 controls but goes down 5. When it's down to five the hidden controls are rotated by a parent node that takes the average of the two controls around it. When they switch back on, the expression is supposed to get the rotation attributes of that average, 0 out the parent node, and then set the attributes of the control to those values, ready for the animator to animate with now, and in the same position before they switch off. In theory it works, except I realized the expression is only calculating through time. So it works if I scrub the time slider, but not when I scrub the attribute driving it.

Is there some way to get it to execute the expression when I scrub an attribute? Or some alternate way, that doesn't use utility nodes, so those attributes are free for animation?

02 February 2011, 11:15 PM
Read in docs about scriptJob command , maybe it is what you looking for.

02 February 2011, 06:45 PM
Oooh. I didn't think about using a script job. Is there a way to create that script job from opening the file though?

02 February 2011, 07:46 PM
Ok, I was going to make a script job that gets created in a script node when the file is opened, but now I get an error when I try to make a global proc of my script, and I'm not sure why. Can anybody enlighten me on this?

Here's the code:

global proc tailFidelity()
if (Tail1_CTRL.tailDriver == 0)
setAttr Tail2_CTRL.rotate -type float3 0 0 0;
setAttr Tail4_CTRL.rotate -type float3 0 0 0;
setAttr Tail6_CTRL.rotate -type float3 0 0 0;
setAttr Tail8_CTRL.rotate -type float3 0 0 0;

if (Tail1_CTRL.tailDriver == 1)
float $tail2Rot[] = `getAttr Tail_2_Average.output3D`;
float $tail4Rot[] = `getAttr Tail_4_Average.output3D`;
float $tail6Rot[] = `getAttr Tail_6_Average.output3D`;
float $tail8Rot[] = `getAttr Tail_8_Average.output3D`;

setAttr Tail2_CTRL.rotate -type float3 $tail2Rot[0] $tail2Rot[1] $tail2Rot[2];
setAttr Tail4_CTRL.rotate -type float3 $tail4Rot[0] $tail4Rot[1] $tail4Rot[2];
setAttr Tail6_CTRL.rotate -type float3 $tail6Rot[0] $tail6Rot[1] $tail6Rot[2];
setAttr Tail8_CTRL.rotate -type float3 $tail8Rot[0] $tail8Rot[1] $tail8Rot[2];

To which I get this back:

// Error: if (Tail1_CTRL.tailDriver == 0)
// Error: Invalid use of Maya object "Tail1_CTRL.tailDriver". //
// Error: if (Tail1_CTRL.tailDriver == 1)
// Error: Invalid use of Maya object "Tail1_CTRL.tailDriver". //

Tail1_CTRL.tailDriver is a float type and just goes 0 to 1. Nothing is connected to it right now that would prevent it from getting changed. The script works when I just add it as mel script rather than a global proc, sooooo, wtf?

02 February 2011, 11:11 PM
You cannot simply use an expression as a mel script. Even if there are a lot of similiar elements, an expression can be quite different. e.g. there are predefined variables like "frame", which is the current frame number.

In normal mel scripts you don't have access to these elements. And in expression you can simply use object attributes or assign them like:

pCube1.tx = 2.0;

This is not possible in a mel script. There the element pCube1 is unknown. If you want to manipulate attributes in a mel script you have to do it via setAttr or get them with getAttr.

BTW: Did you try the approach with the dummy attribute to execute an expression as soon as a object is modified?

02 February 2011, 11:13 PM
One point to take into accout is that script jobs only work from the UI. So if you try to render a sequence in batch where a script job does something important, it will probably fail.

02 February 2011, 11:17 PM
Actually, I started with mel script for this, but have been trying to find some way to run this mel script within the file, without external files or setting something up directly in their copy of Maya.

The script works as straight mel script. But when I make it a global proc, it doesn't work any more. Is that because of the if statement? I swear I've used that before.

Anyway, what I ultimately need is it to run the parts within the if statement when an attribute changes values. How I do that I don't really care as long as it works, and the control remains free for an animator to use, which is why I'm not using utility nodes.

02 February 2011, 11:19 PM
My goal with the script job was to see if I could use an expression that runs when this specific file opens to create the script job and then I could get that if statement running when ever the control attribute changes. I would use an expression to run it, but it seems to only update when the time line changes, not the attribute for some reason.

06 June 2011, 07:58 AM
you could create a conditional statement based on the translation or "action" of a certain object or value somewhere

06 June 2011, 10:10 PM
Not to burst your bubble here...but I think you would be well served to do this with conditional/blend/math nodes and connections. Have a hierarchy of parent locators that are driven by these nodes/constraints.
Any major part of a rig running with expressions can really bog down a scene not to mention behave weirdly...If you can write a plug-in that's a different story...but if that isn't an option, you would get lots more points if you can do it with nodes.
I'm just saying.
Good luck with it.

CGTalk Moderation
06 June 2011, 10:10 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.