[Closed] Buttons and custom attributes
I have a n00b question. On a rig I am building, I’ve made a control object with an attribute holder that contains several sliders wired to finger movement. That much is working. Now I’m trying to use script to add a button that would reset all of my sliders to 0 when clicked. Here’s what I have so far:
ca=attributes HandControls
(
parameters ResetP rollout:ResetR
(
ResetAll type:#integer ui:(RResetBtn)
)
rollout ResetR “Reset”
(
button RResetBtn “Reset Fingers” pos:[15,13] width:136 height:30 enabled:true toolTip:“Resets Finger Sliders to 0”
on RResetBtn pressed do
(
R_Hand_Controler.modifiers[1].Custom_Attributes.Ring_Finger = ResetAll
)
)
custAttributes.add $.modifiers[1] ca
This, of course isn’t working. First off, It returns a syntax error in the final line.
– Syntax error: at name, expected attributes clause:
– In line: custAttributes.
But I’m sure that there are other problems. For one, I couldn’t figure out how max wants me to assign a value of 0 to the ResetAll integer, or if it can even be used as a variable to pass value to my sliders. I’m also quite lost as to defining the button function, mostly due to my lack of familiarity with the syntax and general bahaviour of max script. This was my best attempt so far, but I couldn’t find specific info on this subject. Help would be much appreciated. Thank you.
the reason for the error you are getting is due to unbalanced parentheses; simply put – you’re missing one more ‘)’ before your custAttributes.add command:
ca=attributes HandControls (
parameters ResetP rollout:ResetR (
ResetAll type:#integer ui:(RResetBtn)
)
rollout ResetR "Reset" (
button RResetBtn "Reset Fingers" pos:[15,13] width:136 height:30 enabled:true toolTip:"Resets Finger Sliders to 0"
on RResetBtn pressed do (
R_Hand_Controler.modifiers[1].Custom_Attributes.Ring_Finger = ResetAll
)
)
)
custAttributes.add $.modifiers[1] ca
next up… an ui button doesn’t have any inherent value, it only sits there waiting to be pressed. If you want to set up a default value to reset to with the ResetAll parameter, hook it up to e.g. a spinner ui control instead.
Looks like you just want to reset things to zero, however, zo you could forego that parameter altogether and just let the button press event deal with it, e.g.
R_Hand_Controler.modifiers[1].Custom_Attributes.Ring_Finger = 0
The only problems then remaining are
-
what is R_Hand_Controler?
Is this a variable pointing to an object? If so, that’s fine, as long as you’re sure that object exists (isValidObject)
If it is the name of an object, refer to it as $R_Hand_Controler (or $R_Hand_Controller depending on whether the typo is in the actual object’s name or not) instead. However, keep in mind that if you decide to change the name of that object, this script will break, so it’s better if you do store a reference to the object somewhere in the scene. -
what is .Custom_Attributes?
Objects, modifiers, etc. don’t have a .Custom_Attributes property to get at all the different custom attributes applied to them. If the parameter of one of those custom attributes is called ‘Ring_Finger’, then you can just refer to it as:
R_Hand_Controler.modifiers[1].Ring_Finger = 0
In the unfortunate event that two custom attribute blocks use the same name for two parameters, you can access the specific one using:
R_Hand_Controler.modifiers[1].custAttributes[#HandControls].Ring_Finger = 0
Lastly, beware of using ‘.modifiers[1]’. ‘.modifiers[1]’ refers to the top-most modifier in the modifier stack, not the first modifier applied. So if you add a modifier to an object, the modifier that was originally .modifiers[1] would now be .modifiers[2]. Again, better to store a reference to the appropriate modifier. (which may remove the need to store the object reference, as you’re really only changing the modifier anyway)
Thank you very much for your thorough reply. I will try these suggestions and see if I have any more problems. I’m really enjoying the learning process. By the way, are there any really good online sources for max script tutorials?
Thanks again.
Ok. I re-kajiggered the script to include finger controls with spinners and sliders. I scrapped some of the bad naming as well. Evaluates without errors. The one remaining problem is that the reset button does nothing. I’m guessing it isn’t referencing the sliders properly. So I’m still not understanding how max structures its paths. I tried a variety of options, but nothing works. Here it is:
ca=attributes HandControls (
parameters FingersP rollout:FingersR
(
Index_Finger type:#float ui:(IndexSp,IndexSl)
Middle_Finger type:#float ui:(MiddleSp,MiddleSl)
Ring_Finger type:#float ui:(RingSp,RingSl)
Pinky_Finger type:#float ui:(PinkySp,PinkySl)
)
rollout FingersR "Finger Controls"
(
spinner IndexSp "" range:[-10,45,0]
slider IndexSl "Index Finger" range:[-10,45,0] offset:[0,-20]
spinner MiddleSp "" range:[-10,45,0]
slider MiddleSl "Middle Finger" range:[-10,45,0] offset:[0,-20]
spinner RingSp "" range:[-10,45,0]
slider RingSl "Ring Finger" range:[-10,45,0] offset:[0,-20]
spinner PinkySp "" range:[-10,45,0]
slider PinkySl "Pinky Finger" range:[-10,45,0] offset:[0,-20]
)
parameters ResetP rollout:ResetR
(
ResetAll type:#integer ui:(R_ResetBtn)
)
rollout ResetR "Reset"
(
button R_ResetBtn "Reset Fingers" pos:[15,13] width:136 height:30 enabled:true toolTip:"Resets Finger Sliders to 0"
on RResetBtn pressed do
(
R_Hand_Controller.modifiers[1].HandControls.IndexSp = 0
R_Hand_Controller.modifiers[1].HandControls.Middle_Finger = 0
R_Hand_Controller.modifiers[1].HandControls.Ring_Finger = 0
R_Hand_Controller.modifiers[1].HandControls.Pinky_Finger = 0
)
)
)
custAttributes.add $.modifiers[1] ca
R_Hand_Controller is the control object for the hand on my rig.
-
If R_Hand_Controller is an actual object name, use $R_Hand_Controller . If R_Hand_Controller is a variable, and it points to the correct object, it should already be fine.
-
Your button is called ‘R_ResetBtn’ but your event is set up for ‘RResetBtn’, so that event will never trigger
-
You’re accessing the UI controls (e.g. IndexSp) when you’ll want to access the parameters (i.e. Index_Finger)
-
If these are the parameters within the same custom attribute definition, then you can skip the whole object/modifier/etc. pathing and use ‘this’ instead. E.g. “this.Index_Finger = 0”
Ha ha, yes. Thank you for looking over my code. I did miss a few things including removing that reference to the ui spinner (when I was testing to see whether that would work). Using “this.” works perfectly. I would still like to know how to access a specific variable in full, but mainly to understand it for later use rather than use it in this case. Sir, I am in your debt.
I think I’ll be able to figure out the rest or at least clobber my way through it via trial and error.:wip: