[Closed] SubAnim from Property
Does anybody know how to reliably get the SubAnim from a node’s Property (via MXS)?
Here is an example for a Target Spotlight:
getPropNames $.baseobject gives me the property: “#nearAttenEnd”
So to try and get to the SubAnim (to pass into a script controller) I would normally do:
$.baseObject[#nearAttenEnd]
That usually works, but for Attenuation it doesn’t, because the SubAnim is named differently then the property:
Property: #nearAttenEnd
SubAnim: #Attenuation_Near_End
That to me is sooo typical Max, everything just slapped together as usual.
Anyway, if you know a way around, I would really appreciate it!
Thanks!
…will this work for you?
num = $.baseobject.numsubs
thearray = #()
for i = 1 to num do
(
append thearray (($.baseobject[i].name) as name)
)
for o in thearray do print o
Oh… just found this in the help:
getSubAnimNames $.baseobject
Do you actually need to get it from the properties or can you just skip straight to the subanims?
It might be typical max that there’s no built-in method to get the subAnim name from a property name, but the fact that they’re different has more to do with internal names (property) vs display names (subAnims) for e.g. localization purposes.
Usually (I think ‘always’, but I’ll err on the side of caution), you can get the subAnim name through showProperties (this does mean you’ll need an instance of the maxwrapper);
props = stringStream ""
StringStream:""
showProperties $ to:props
false
props = props as string
" .aspect (Aspect_Ratio) : float
.rgb (Color/color) : RGB color
.contrast : float"
props = filterString props "
"
#(" .aspect (Aspect_Ratio) : float", " .rgb (Color/color) : RGB color", " .contrast : float", ...)
myProp = for p in props where (findString p ".nearAttenEnd " != undefined) collect ( p )
#(" .nearAttenEnd (Attenuation_Near_End) : float")
mySub = (filterString myProp[1] "()")[2] as name
#Attenuation_Near_End
or in function form…
fn getSubAnimNameFromPropName obj prop = (
if (classOf prop == name) then ( prop = prop as string )
if (prop[1] == ".") then ( prop = subString prop 2 -1 )
local props = stringStream ""
showProperties obj to:props
props = props as string
props = filterString props "
"
myProp = for p in props where (findString p ("." + prop + " ") != undefined) collect ( p )
if (myProp.count == 0) then ( undefined )
else if (myProp.count == 1) then ( (filterString myProp[1] "()")[2] as name )
else ( throw "More than 1 property matched - un-possible!" )
)
getSubAnimNameFromPropName $ #foo
getSubAnimNameFromPropName $ #nearAttenEnd
getSubAnimNameFromPropName $ "nearAttenEnd"
getSubAnimNameFromPropName $ ".nearAttenEnd"
If the property has a controller attached, you can also look for that controller in the subanims (loop over them and compare controllers), but keep in mind that a controller may be instanced to completely unrelated subAnim tracks.
Yes I find it pretty poor that the two are so disconnected that you have to print stuff to strings etc to be able to find the connection. That is typical Max imo. Nobody should ever have to deal with localization strings to access property subAnims.
Anyway, I really appreciate the solution!
Thanks!
I think that Richard answered it but you need to always use getSubAnimName to get the sub anims tracks. Or if you are using getPropNames you need to use getProperty.
I think I will just use getSubAnimNames like some of you suggested.
It won’t give me the non-animatable properties (like getPropNames does), but that is ok in this case since i need to be able to pass this into a scrip controller anyway.
Edit: I also noticed that ‘GetProperty’ is ok with either the ‘GetPropNames’ name or the ‘SubAnim’ name to return a value.
So that saves me from having to re-write a lot of code.
I can just replace the ‘GetPropNames’ by the SubAnim functions instead and be mostly done.
thanks again all!