PDA

View Full Version : GetAttr and setAttr not working through float.


TechnicallyArtistic
02-22-2011, 05:41 PM
I'm trying to rig up a tail with more controls than I would like but I don't want to loose the fidelity of less controls on a lot of joints. To deal with that i want to have two level of controls available. One level would be half the controls and the other would be a control per a joint. When the controls are halved, the in between controls are then driven by an average of the two control around it. When they're being driven by the average, a parent node is getting the rotation. When they're on full controls the idea is to take the rotation from that parent group and paste it onto the control the animator would use, and 0 out the parent group. Then when going back to half controls, 0 out the control, and set the parent group back to being the average.

I can control the parent group through an average node and a blend node, but the animation control I need to do through expression, to keep it freed up for the animator. Right now I have a getAttr and setAttr that works through mel but it doesn't seem to be working through the expression, via if statement. Anybody have any ideas why this wouldn't work? Worst case scenario is I scrap it and there's just a bunch of controls which isn't a big deal, but this seems like it should work.

Here's the expression.
if (Tail1_CTRL.tailDriver == 0)
{
setAttr Tail2_CTRL.rx 0;
setAttr Tail4_CTRL.rx 0;
setAttr Tail6_CTRL.rx 0;
setAttr Tail8_CTRL.rx 0;
setAttr Tail2_CTRL.ry 0;
setAttr Tail4_CTRL.ry 0;
setAttr Tail6_CTRL.ry 0;
setAttr Tail8_CTRL.ry 0;
setAttr Tail2_CTRL.rz 0;
setAttr Tail4_CTRL.rz 0;
setAttr Tail6_CTRL.rz 0;
setAttr Tail8_CTRL.rz 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];
}

else
{
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];
}

Right now when I run it neither of the float expressions are getting applied. Any ideas why?

WesHowe
02-22-2011, 05:58 PM
I'm not sure if this is it, but what type is the ".tailDriver" attribute? Is it a float?

In your code you are comparing that to ints. Since you are not using an else, if the values are neither 0 nor 1 (for instance something in-between the two) neither block will execute.

<* Wes *>

TechnicallyArtistic
02-22-2011, 06:31 PM
It is a float. But it's going from 0 to 1. Everything in between is transition. It's not stopping any where in between. And even if it wasn't running the 0 part when starting and going to 1 that would make sense. But that it doesn't run either as I scrub through seems strange.

haggi
02-22-2011, 07:33 PM
Hmmm. In this simple form it works fine for me.

if( ctrl.driver == 0) {
setAttr pCube1.rotate 0 0 0;
}

TechnicallyArtistic
02-22-2011, 07:51 PM
It sorta works for me on that level too, but that's no the issue.

When I first add the expression, if the control is on one of those values, it will update. But it I scrub the control to either side, it does not. Does it work with something similar to this? I'm gonna post the code because It's slightly simplified again. But a single value seems to work, but not on the scrub, and it doesn't switch between the two.


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];
}

TechnicallyArtistic
02-22-2011, 07:58 PM
Ah. Ok, I see what my problem it. And I should have realized this, but it's only executing when animation plays.

Does anybody know of a way to get it to activate on the switch, and not on time?

uiron
02-22-2011, 10:25 PM
if i'm reading it right, you want to run this code in expression - don't do that, get/set attr can really mess things up.

try to get away without expressions instead, looks like condition nodes would do just fine here.

haggi
02-22-2011, 10:37 PM
If you still need this in an expression, you need a direct connection so that the expression is executed.
A direct connection would be something like:

dummyLocator.tx = 0.0;

This way the expression should be executed. But as already mentioned by urion, condition nodes should work fine here, and you have direct connections and no update problems.

TechnicallyArtistic
02-22-2011, 10:41 PM
Does that leave the control free to key frame by hand though?
I know I can use a direct connection, the issue is it doesn't leave it free to animate by hand.

What I'm trying to get is so half the controls to go from manual to automatic, and on manual, the attributes are free for key frame animation by an animator.

haggi
02-22-2011, 10:48 PM
You need a dummy object or attribute. You can simply add an arbitrary attribute to your controller and set it in the expression.

Imagine you have a polycube and a locator called "ctrl". Add a float attribute called dummy to your locator. Then this expression works and lets the cube rotate slowly:

ctrl.dummy = 0; if( ctrl.translateY > 1.0)
{
float $r[3] = `getAttr pCube1.rotate`;
setAttr pCube1.rotate ($r[0]+.5) $r[1] $r[2];
}else{
setAttr pCube1.rotate 0 0 0;
}

CGTalk Moderation
02-22-2011, 10:48 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.